package com.marvels.financial.loan.api.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.fintech.third.service.message.SmsService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.marvels.approve.common.dto.EdcSharedDataDTO;
import com.marvels.approve.common.service.SharedDataMqProvideApi;
import com.marvels.common.constants.LoanStateConstant;
import com.marvels.common.constants.MarvelsConstant;
import com.marvels.common.dto.MarvelsResultDTO;
import com.marvels.common.dto.SynLoanStatus2ApplyDTO;
import com.marvels.common.dto.UserDTO;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.exception.MarvelsErrorCode;
import com.marvels.common.utils.CacheUtils;
import com.marvels.common.utils.CommonProperties;
import com.marvels.common.utils.DateUtils;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.MarvelsUtils;
import com.marvels.common.utils.PageConverter;
import com.marvels.financial.collection.dao.OverdueCollectTaskDao;
import com.marvels.financial.consum.FinancialConsumerUmApi;
import com.marvels.financial.funds.dto.CmsEmployeeInfoDTO;
import com.marvels.financial.loan.api.FinancialILoanAfterInfoApi;
import com.marvels.financial.loan.api.FinancialILoanAfterInfoForCommonApi;
import com.marvels.financial.loan.api.IProductInfoApi;
import com.marvels.financial.loan.dao.McfeCustomerLoanContractDao;
import com.marvels.financial.loan.dao.McfeCustomerLoanInfoDao;
import com.marvels.financial.loan.dao.McfeCustomerRepaymentPlanDao;
import com.marvels.financial.loan.dao.McfeCustomerRepaymentPlanLogDao;
import com.marvels.financial.loan.dao.McfeLateFeeDao;
import com.marvels.financial.loan.dao.McfeLoanWithholdingDao;
import com.marvels.financial.loan.dao.McfeLoanWithholdingDetailDao;
import com.marvels.financial.loan.dao.McfePenaltyFeeDao;
import com.marvels.financial.loan.dao.McfeRepaymentFlowDao;
import com.marvels.financial.loan.dao.McfeReversalDetailDao;
import com.marvels.financial.loan.dao.McfeReversalFlowDao;
import com.marvels.financial.loan.dao.McfeWithholdingBankLimitDao;
import com.marvels.financial.loan.dto.AmountDTO;
import com.marvels.financial.loan.dto.ApprovalProcessConditionDTO;
import com.marvels.financial.loan.dto.HandleWithholePaymentDTO;
import com.marvels.financial.loan.dto.LoanAfterInfoDTO;
import com.marvels.financial.loan.dto.LoanTrailDTO;
import com.marvels.financial.loan.dto.McfeCustomerLoanContractDTO;
import com.marvels.financial.loan.dto.McfeCustomerLoanInfoDTO;
import com.marvels.financial.loan.dto.McfeCustomerRepaymentPlanDTO;
import com.marvels.financial.loan.dto.McfeLoanWithholdingDTO;
import com.marvels.financial.loan.dto.McfeLoanWithholdingDetailDTO;
import com.marvels.financial.loan.dto.McfeRepaymentFlowDTO;
import com.marvels.financial.loan.dto.McfeReversalDetailDTO;
import com.marvels.financial.loan.dto.McfeReversalFlowDTO;
import com.marvels.financial.loan.dto.McfeWithholdingBankLimitDTO;
import com.marvels.financial.loan.dto.McptAmortMethodDTO;
import com.marvels.financial.loan.dto.McptConsultingFeeDTO;
import com.marvels.financial.loan.dto.McptLateFeeDTO;
import com.marvels.financial.loan.dto.McptPaymentSequenceItemDTO;
import com.marvels.financial.loan.dto.McptPenaltyFeeDTO;
import com.marvels.financial.loan.dto.McptPreTerminationFeeDTO;
import com.marvels.financial.loan.dto.McptProduct;
import com.marvels.financial.loan.dto.OverDueCustApiDTO;
import com.marvels.financial.loan.dto.PaymentResponse;
import com.marvels.financial.loan.dto.ProductMsgInfoDTO;
import com.marvels.financial.loan.service.ILoanApplyMqProduct;
import com.marvels.financial.loan.service.WithholdPaymentApi;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import net.sf.json.JSONObject;


@Service
public class FinancialLoanAfterInfoApiImpl implements FinancialILoanAfterInfoApi {
	@Autowired
	private FinancialILoanAfterInfoForCommonApi loanAfterInfoForCommonService;//普通生成还款计划
	@Autowired
	private McfeCustomerRepaymentPlanDao mcfeCustomerRepaymentPlanDao;//还款计划表服务
	@Autowired
	private McfeCustomerLoanContractDao mcfeCustomerLoanContractDao;//合同表服务
	@Autowired
	private McfeCustomerLoanInfoDao mcfeCustomerLoanInfoDao;//客户贷款信息服务
	@Autowired
	private McfeLoanWithholdingDao mcfeLoanWithholdingDao;//咨询费代扣总表
	@Autowired
	private McfeWithholdingBankLimitDao mcfeWithholdingBankLimitDao;//限额表
	@Autowired
	private McfeLoanWithholdingDetailDao mcfeLoanWithholdingDetailDao;//咨询费代扣明细表
	@Autowired
	private IProductInfoApi iProductInfoApi;//调用产品服务
	@Autowired
	private McfeRepaymentFlowDao mcfeRepaymentFlowDao;//还款流水表服务
	@Autowired
	private McfeReversalFlowDao mcfeReversalFlowDao;//冲销还款计划流水
	@Autowired
	private McfeReversalDetailDao mcfeReversalDetailDao;
	@Autowired
	private McfeCustomerRepaymentPlanLogDao mcfeCustomerRepaymentPlanLogDao;
	@Autowired
	private WithholdPaymentApi  withholdPaymentApi ;
	@Autowired
	private FinancialConsumerUmApi consumerUmApi;
	
	@Autowired
	private McfePenaltyFeeDao mcfePenaltyFeeDao;
	@Autowired
	private McfeLateFeeDao mcfeLateFeeDao;

	@Autowired
	private SharedDataMqProvideApi sharedDataMqProvideApi;
	
	@Autowired
	private SmsService smsService;
	@Value("${loanid.prefix}")
	private String loanidPrefix;
	@Autowired
	private ILoanApplyMqProduct iLoanApplyMqProduct;
	
	@Autowired
	private OverdueCollectTaskDao overdueCollectTaskDao;
	
	@Override//还款试算
	public LoanAfterInfoDTO loanTrial(LoanAfterInfoDTO loanAfterInfo) throws MarvelsBusinessException {
		if (loanAfterInfo == null) {
			throw new MarvelsBusinessException("传入参数为空");
		}
		LoanAfterInfoDTO loanAfter = createLoanAfterInfoForCommon(loanAfterInfo);
		
		return loanAfter;
	}

	/**
	 * 
	* @Title: loanApplySuccess 
	* @Description:贷款成功--生成还款计划
	* @param loanAfterInfo
	* @return
	* @throws MarvelsBusinessException       
	* @author 
	* @date 2018年11月1日 下午2:22:38
	 */
	@Override
	@Transactional//生成还款计划
	public LoanAfterInfoDTO loanApplySuccess(LoanAfterInfoDTO loanAfterInfo) throws MarvelsBusinessException {
		LoanAfterInfoDTO loanAfter = null;
		loanAfter = createContractAndLoanPlanForCommon(loanAfterInfo);
		//更新ac_trace状态
		SynLoanStatus2ApplyDTO synLoanStatus2ApplyDTO=new SynLoanStatus2ApplyDTO();
		synLoanStatus2ApplyDTO.setLoanId(loanAfterInfo.getLoanId());
		synLoanStatus2ApplyDTO.setOriginalState(LoanStateConstant.F03);
		synLoanStatus2ApplyDTO.setStatus(LoanStateConstant.D01);
		try {
			iLoanApplyMqProduct.synLoanStatus2Apply(synLoanStatus2ApplyDTO);
		} catch (MarvelsBusinessException e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:"+loanAfterInfo.getLoanId()+"放款成功处理推消息修改状态异常:",e);
		}
		
		//将放款成功数据推送到共享数据
		EdcSharedDataDTO dataDTO=new EdcSharedDataDTO();
		dataDTO.setCreatedBy("system");
		dataDTO.setCreatedDate(new Date());
		dataDTO.setCustName(loanAfterInfo.getCustName());
		dataDTO.setCustCardNo(loanAfterInfo.getCustCardNo());
		dataDTO.setLoanId(loanAfterInfo.getLoanId());
		dataDTO.setMobileNo(loanAfterInfo.getMobile());
		dataDTO.setSrc(loanidPrefix);
		dataDTO.setStatus("3");
		dataDTO.setUpdatedDate(new Date());
		dataDTO.setUpdatedBy("system");
		try {
			sharedDataMqProvideApi.synSharedData(dataDTO);
		} catch (MarvelsBusinessException e) {
			MarvelsLogUtil.getInstance().error(">>>>>>loanId:"+loanAfterInfo.getLoanId()+",共享数据同步异常:",e);
		}
		try {
			MarvelsLogUtil.getInstance().info(">>>>loanId:"+loanAfterInfo.getLoanId()+",放款成功发送短信开始");
			net.sf.json.JSONObject jsonObject=new net.sf.json.JSONObject();
			jsonObject.put("phone", loanAfterInfo.getMobile());
			jsonObject.put("template_id", "5");
			jsonObject.put("src", "loanSuccess");
			jsonObject.put("create_time",DateUtils.getDateYYYY_MM_DD_HH_MM_SS(new Date()));
			jsonObject.put("userName", loanAfterInfo.getCustName());
			jsonObject.put("product", loanAfterInfo.getProductTypeName());
			jsonObject.put("amount", loanAfterInfo.getAmount().setScale(2,BigDecimal.ROUND_HALF_UP));
			jsonObject.put("loanDay",DateUtils.getDateYYYY_MM_DD(new Date()));
			int size=loanAfterInfo.getPaymentAcctNo().length();
			jsonObject.put("receiveAcct", loanAfterInfo.getPaymentAcctNo().substring(size-4,size));
			smsService.sendSms(jsonObject);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>loanId:"+loanAfterInfo.getLoanId()+",放款成功发送短信失败",e);
		}
		return loanAfter;
	}

	
	/**
	 * 试算接口
	 * 
	 * @author 娄凯琦
	 * @date 2018年5月8日
	 * @param LoanAfterInfo
	 * @return
	 * @throws MarvelsBusinessException
	 */
	private LoanAfterInfoDTO createLoanAfterInfoForCommon(LoanAfterInfoDTO loanAfterInfo)
			throws MarvelsBusinessException {
		// 调用生成合同和还款计划方法
		McfeCustomerLoanContractDTO contract = loanAfterInfoForCommonService.createLoanAfterInfo(loanAfterInfo);
		// 设置成功后的响应信息
		LoanTrailDTO returnDto = initBean(contract);
		List<McfeCustomerRepaymentPlanDTO> planList = contract.getPlanList();
		List<McfeCustomerRepaymentPlanDTO> paymentPlanInfos = new ArrayList<McfeCustomerRepaymentPlanDTO>();
		for (McfeCustomerRepaymentPlanDTO mpPaymentPlanInfo : planList) {
			McfeCustomerRepaymentPlanDTO planInfo = new McfeCustomerRepaymentPlanDTO();
			BeanUtils.copyProperties(mpPaymentPlanInfo, planInfo);
			paymentPlanInfos.add(planInfo);
		}
		returnDto.setPlanInfo(paymentPlanInfos);
		// 到手金额
		BigDecimal aviAmount = contract.getAmount()
				.subtract(contract.getConsultingFee().add(contract.getConsultingFeeOs()));

		McfeCustomerRepaymentPlanDTO plan = planList.get(0);
		// 每月应还金额
		BigDecimal monthlyAmount = plan.getPrincipal().add(plan.getInterest().add(plan.getManagementFee()));
		loanAfterInfo.setAviAmount(aviAmount);
		loanAfterInfo.setMonthlyAmount(monthlyAmount);
		loanAfterInfo.setManagementFee(contract.getManagementFeeOs());
		loanAfterInfo.setLoanTrailDTO(returnDto);
		MarvelsLogUtil.getInstance().info("--贷款试算服务-end---");
		return loanAfterInfo;
	}

	/**
	 * 初始化试算实体
	 * 
	 * @param contract
	 * @return
	 */
	private LoanTrailDTO initBean(McfeCustomerLoanContractDTO contract) {
		LoanTrailDTO bean = new LoanTrailDTO();
		// 总还款金额
		bean.setTotalAmount(contract.getPrincipalOs().add(contract.getInterestOs()).add(contract.getManagementFee())
				.add(contract.getConsultingFee()));
		// 本金
		bean.setPrincial(contract.getPrincipalOs());
		// 总利息
		bean.setInterest(contract.getInterestOs());
		// 首次还款日
		bean.setFirstPaymentDate(contract.getFirstPaymentDate());
		// 首次还款金额
		bean.setFirstPaymentAmount(contract.getFirstPaymentAmount());
		// 最后还款日期
		bean.setLastPaymentDate(contract.getLastPaymentDate());
		// 最后还款金额
		bean.setLastPaymentAmount(contract.getLastPaymentAmount());
		return bean;
	}

	/**
	 * 通用生成合同和还款计划(写入表)
	 * 
	 * @author 娄凯琦
	 * @date 2018年5月14日
	 * @param loanAfterInfo
	 * @return
	 * @throws MarvelsBusinessException
	 */
	
	private LoanAfterInfoDTO createContractAndLoanPlanForCommon(LoanAfterInfoDTO loanAfterInfo)
			throws MarvelsBusinessException {
		// 调用生成合同和还款计划方法
		McfeCustomerLoanContractDTO contract = loanAfterInfoForCommonService.createLoanAfterInfo(loanAfterInfo);
		String createdBy = "";
		String updateBy = "";
		UserDTO userDTO = null;
		try {
			userDTO = CacheUtils.getCacheUser();
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>获取当前用户信息异常:", e);
		}
		if (userDTO == null) {
			createdBy = "system";
			updateBy = "system";
		} else {
			createdBy = userDTO.getUserCode();
			updateBy = userDTO.getUserCode();
		}
		contract.setCreatedBy(createdBy);
		contract.setUpdatedBy(updateBy);
		mcfeCustomerLoanContractDao.insertCustomerLoanContract(contract);//合同信息入库

		
		//插入到贷款用户信息表开始
		McfeCustomerLoanInfoDTO CustomerLoanInfo = contract.getCustomerLoanInfo();
		CustomerLoanInfo.setCreatedBy(createdBy);
		CustomerLoanInfo.setUpdatedBy(updateBy);
		customerLoanInfoCommon(CustomerLoanInfo);
		//插入到贷款用户信息表开始
		//插入还款计划表开始
		List<McfeCustomerRepaymentPlanDTO> planList = contract.getPlanList();
		Iterator<McfeCustomerRepaymentPlanDTO> it = planList.iterator();	
		while (it.hasNext()) {
			McfeCustomerRepaymentPlanDTO plan = (McfeCustomerRepaymentPlanDTO) it.next();
//			if (plan.getTenor() == 1) {
//				// 按照新需求，做砍头息处理
//				cutInterest(plan, contract, CustomerLoanInfo, mcptConsultingFeeDTO);
//			}
//			String test = null;
//			System.out.println(test.equals(null));
			plan.setCreatedBy(createdBy);
			plan.setUpdatedBy(updateBy);
			mcfeCustomerRepaymentPlanDao.insertRepaymentPlan(plan);
			//保存还款计划
		}
		//插入还款计划表结束
		
		//插入违约金和滞纳金参数表开始
		McptPenaltyFeeDTO paramPenalty = contract.getMcptPenaltyFeeDTO();
		McptLateFeeDTO paramLate = contract.getMcptLateFeeDTO();
		paramPenalty.setLoanId(loanAfterInfo.getLoanId());
		paramLate.setLoanId(loanAfterInfo.getLoanId());
		mcfePenaltyFeeDao.insertMcfePenaltyFee(paramPenalty);
		mcfeLateFeeDao.insertMcfeLateFee(paramLate);
		//插入违约金和滞纳金参数表结束
		loanAfterInfo.setContract(contract);
		return loanAfterInfo;
	}

	/**
	 * 砍头息处理逻辑
	 * 
	 * @param planInfo
	 * @param contract
	 * @param account
	 * @param monetaryTxnInfos
	 * @param feeObjs
	 */
	private void cutInterest(McfeCustomerRepaymentPlanDTO planInfo, McfeCustomerLoanContractDTO contract,
			McfeCustomerLoanInfoDTO account, McptConsultingFeeDTO mcptConsultingFeeDTO) {
		// 一次收取
		if (MarvelsConstant.CHARGE_METHOD_ONE_TIME_CHARGE.equalsIgnoreCase(mcptConsultingFeeDTO.getChargeMethod())) {
			planInfo.setConsultingFeeAct(planInfo.getConsultingFee());
			account.setConsultingFee(planInfo.getConsultingFee());
			account.setConsultingFeeOs(BigDecimal.ZERO);
			contract.setConsultingFee(planInfo.getConsultingFee());
			contract.setConsultingFeeOs(BigDecimal.ZERO);
		}
	}

	/**初始化咨询费代扣流水
	 * @author 娄凯琦
	 * @date 2018年5月17日  
	 * @param loanAfterInfo
	 * @throws MarvelsBusinessException
	 */
	@Override
	@Transactional
	public void initLoanWithholding(LoanAfterInfoDTO loanAfterInfo) throws MarvelsBusinessException {
		if(loanAfterInfo ==null){
			throw new MarvelsBusinessException("传入参数不能为空");
		}
		if(loanAfterInfo.getConsultingFee()==BigDecimal.ZERO){
			return;
		}
		MarvelsLogUtil.getInstance().info("this initLoanWithholding loanId =====>"+loanAfterInfo);
		//查询是否存在咨询费代扣流水
		List<McfeLoanWithholdingDTO> consultList= mcfeLoanWithholdingDao.selectLoanWithholding(loanAfterInfo);
		if(consultList!=null && consultList.size()>=1){
			McfeLoanWithholdingDetailDTO deleteDto = new McfeLoanWithholdingDetailDTO();
			deleteDto.setDeleteFlag(1);
			deleteDto.setLoanId(loanAfterInfo.getLoanId());
			McfeLoanWithholdingDTO tmp = consultList.get(0);
			tmp.setDeleteFlag(1);
			mcfeLoanWithholdingDao.updateLoanWithholding(tmp);//逻辑删除咨询费代扣流水
			mcfeLoanWithholdingDetailDao.updateLoanWithholdingDetail(deleteDto);//逻辑删除代扣流水
		}
		McfeWithholdingBankLimitDTO withholdingBankLimitDTO = mcfeWithholdingBankLimitDao.selectWithholdingBankLimitDTO(loanAfterInfo);//查询银行限额
		if(withholdingBankLimitDTO == null){
			throw new MarvelsBusinessException("查找不到对应的银行限额,生成咨询费代扣流水失败");
		}
		
		McfeLoanWithholdingDTO newWithholdingDTO = new McfeLoanWithholdingDTO();
		newWithholdingDTO.setCustCardNo(loanAfterInfo.getCustCardNo());
		newWithholdingDTO.setCustName(loanAfterInfo.getCustName());
		newWithholdingDTO.setMobile(loanAfterInfo.getMobile());
		newWithholdingDTO.setLoanId(loanAfterInfo.getLoanId());
		newWithholdingDTO.setAmount(loanAfterInfo.getAmount());
		newWithholdingDTO.setBankCardNo(loanAfterInfo.getPaymentAcctNo());
		newWithholdingDTO.setBankName(loanAfterInfo.getPaymentBankName());
		newWithholdingDTO.setBankHeadLink(loanAfterInfo.getPaymentBankHead());
		newWithholdingDTO.setTransctionSeq(MarvelsUtils.generateUUIDCode("ZXF"));
		newWithholdingDTO.setTranctionDate(new Date());
		newWithholdingDTO.setStatus("S0");
		newWithholdingDTO.setFundCode(loanAfterInfo.getFundSource());
		newWithholdingDTO.setFundName(loanAfterInfo.getFundName());
		newWithholdingDTO.setProductType(loanAfterInfo.getProductType());
		newWithholdingDTO.setProductTypeName(loanAfterInfo.getProductTypeName());
		newWithholdingDTO.setProductCode(loanAfterInfo.getProductCode());
		newWithholdingDTO.setProductName(loanAfterInfo.getProductName());
		newWithholdingDTO.setChannelCode(loanAfterInfo.getChannelCode());
		newWithholdingDTO.setChannelName(loanAfterInfo.getChannelName());
		newWithholdingDTO.setCreatedBy(loanAfterInfo.obtainLoginUserName());
		newWithholdingDTO.setUpdatedBy(loanAfterInfo.obtainLoginUserName());
		
		BigDecimal amountSigLimit = withholdingBankLimitDTO.getAmountSigLimit();//银行单笔限额
		BigDecimal consultingFee = loanAfterInfo.getConsultingFee();//咨询费
		int payCount = 0;//分割期数
		List<McfeLoanWithholdingDetailDTO> detailList= new ArrayList<McfeLoanWithholdingDetailDTO>();
		do{
			payCount++;
			McfeLoanWithholdingDetailDTO dParam = new McfeLoanWithholdingDetailDTO();
			dParam.setCustCardNo(loanAfterInfo.getCustCardNo());
			dParam.setCustName(loanAfterInfo.getCustName());
			dParam.setMobile(loanAfterInfo.getMobile());
			dParam.setLoanId(loanAfterInfo.getLoanId());
			dParam.setAmount(loanAfterInfo.getAmount());
			dParam.setBankCardNo(loanAfterInfo.getPaymentAcctNo());
			dParam.setBankName(loanAfterInfo.getPaymentBankName());
			dParam.setBankHeadLink(loanAfterInfo.getPaymentBankHead());
			dParam.setTransctionSeq(newWithholdingDTO.getTransctionSeq());
			dParam.setTranctionDate(newWithholdingDTO.getTranctionDate());
			dParam.setStatus("S0");
			dParam.setPayIndex(payCount);
			dParam.setFundCode(loanAfterInfo.getFundSource());
			dParam.setFundName(loanAfterInfo.getFundName());
			dParam.setProductType(loanAfterInfo.getProductType());
			dParam.setProductTypeName(loanAfterInfo.getProductTypeName());
			dParam.setProductCode(loanAfterInfo.getProductCode());
			dParam.setProductName(loanAfterInfo.getProductName());
			dParam.setChannelCode(loanAfterInfo.getChannelCode());
			dParam.setChannelName(loanAfterInfo.getChannelName());
			dParam.setCreatedBy(loanAfterInfo.obtainLoginUserName());
			dParam.setUpdatedBy(loanAfterInfo.obtainLoginUserName());
			if(consultingFee.compareTo(amountSigLimit)>=1){//判断应收咨询费是否大于银行限额
				dParam.setAmount(amountSigLimit);
			}else{
				dParam.setAmount(consultingFee);
			}
			consultingFee = consultingFee.subtract(amountSigLimit);	
			detailList.add(dParam);
		}while(consultingFee.compareTo(BigDecimal.ZERO) > 0);
		newWithholdingDTO.setPayCount(payCount);
		mcfeLoanWithholdingDao.insertLoanWithholding(newWithholdingDTO);
		mcfeLoanWithholdingDetailDao.insertLoanWithholdingDetail(detailList);
	}

	
	
	@Transactional
	public void genLoanWithholding(LoanAfterInfoDTO loanAfterInfo) throws MarvelsBusinessException{
		if(loanAfterInfo ==null){
			throw new MarvelsBusinessException("传入参数不能为空");
		}
		McfeLoanWithholdingDetailDTO mcfeLoanWithholdingDetailDTO = new McfeLoanWithholdingDetailDTO();
		mcfeLoanWithholdingDetailDTO.setLoanId(loanAfterInfo.getLoanId());
		//查询咨询费用详细数据
		List<McfeLoanWithholdingDetailDTO> detailList =  mcfeLoanWithholdingDetailDao.selectLoanWithholdingDetail(mcfeLoanWithholdingDetailDTO);
		List<McfeLoanWithholdingDTO> list = mcfeLoanWithholdingDao.selectLoanWithholding(loanAfterInfo);//查询汇总数据
		McfeLoanWithholdingDTO withHolddto = null;
		if(list!=null&&list.size()>0){
			withHolddto = list.get(0);
		}
		int payCount = 0;
		for(McfeLoanWithholdingDetailDTO dto:detailList){	
			if(dto!=null&&"D0".equals(dto.getStatus())&&dto.getAmount()!=null&&BigDecimal.ZERO.compareTo(dto.getAmount())==-1){
				Map<String,String> resultMap = paymentConsultingFee(dto);
				mcfeLoanWithholdingDetailDTO.setStatus(resultMap.get("status"));
				mcfeLoanWithholdingDetailDTO.setResChannel(resultMap.get("payChannel"));
				mcfeLoanWithholdingDetailDTO.setRtnResponseCode(resultMap.get("code"));
				mcfeLoanWithholdingDetailDTO.setRtnResponseMsg(resultMap.get("msg"));
				mcfeLoanWithholdingDetailDTO.setRtnOrderNo(resultMap.get("orderNum"));
				if("0".equals(resultMap.get("code"))){
					mcfeLoanWithholdingDetailDTO.setAmountAct(dto.getAmount());
					payCount++;//判断是否扣所有笔咨询费()
					if(withHolddto!=null){
						withHolddto.setAmountAct(withHolddto.getAmountAct().add(dto.getAmount()));
					}
				}
				mcfeLoanWithholdingDetailDao.updateLoanWithholdingDetail(mcfeLoanWithholdingDetailDTO);
				
			}
		}
		if(withHolddto!=null){
			if(payCount==withHolddto.getPayCount()){//判断是否扣所有笔咨询费()
				withHolddto.setStatus("S1");
			}else{
				withHolddto.setStatus("S2");
			}
			mcfeLoanWithholdingDao.updateLoanWithholding(withHolddto);
		}
	}
	
	/**代扣咨询费
	 * @author 娄凯琦
	 * @date 2018年5月17日  
	 * @return
	 */
	private Map<String,String> paymentConsultingFee(McfeLoanWithholdingDetailDTO dto){
		MarvelsLogUtil.getInstance().info("the McfeLoanWithholdingDetail is withhold ,the loanId ====="+dto.getLoanId());
		HandleWithholePaymentDTO handleWithholePaymentDTO = new HandleWithholePaymentDTO();
		handleWithholePaymentDTO.setAmount(dto.getAmount());
		handleWithholePaymentDTO.setFundSource(dto.getFundCode());
		handleWithholePaymentDTO.setReqNo(dto.getTransctionSeq());
		handleWithholePaymentDTO.setCustName(dto.getCustName());
		handleWithholePaymentDTO.setBankName(dto.getBankName());
		handleWithholePaymentDTO.setCustBankAccountNo(dto.getBankCardNo());
		handleWithholePaymentDTO.setRemark("");
		handleWithholePaymentDTO.setCustBindPhoneNo(dto.getMobile());
		handleWithholePaymentDTO.setCustBankAcctType("1");
		handleWithholePaymentDTO.setCustId(dto.getCustCardNo());
		handleWithholePaymentDTO.setMerchantTreatyNo("");
		PaymentResponse paymentResponse =withholdPaymentApi.withholdPayment(handleWithholePaymentDTO);
		Map<String,String>	resultParam = new HashMap<String,String>();
		if(paymentResponse==null){
			resultParam.put("code", "999");
        	resultParam.put("msg", "代扣出错");
        	resultParam.put("status", "D2");
        	resultParam.put("payChannel", "");
		}else if(MarvelsConstant.TIMEOUT.equalsIgnoreCase(paymentResponse.getCode())
                || MarvelsConstant.PROCESSING.equalsIgnoreCase(paymentResponse.getCode())){
			resultParam.put("code", "999");
        	resultParam.put("msg", "代扣出错,查询超时");
        	resultParam.put("orderNum",paymentResponse.getOrderNumber());
        	resultParam.put("status", "D2");
        	resultParam.put("payChannel", paymentResponse.getChannel());
		}else if(MarvelsConstant.SUCCESS.equalsIgnoreCase(paymentResponse.getCode())) {//成功
            //返回交易码
        	resultParam.put("code", MarvelsConstant.SUCCESS);
            //返回描述
        	resultParam.put("msg", paymentResponse.getMsg());
            //响应方流水号
        	resultParam.put("orderNum",paymentResponse.getOrderNumber());
            //流水状态
        	resultParam.put("status", "D1");    	
        	//代扣成功，将金额累加到三张表中    	
        	resultParam.put("payChannel", paymentResponse.getChannel());
        }else{
        	resultParam.put("code",paymentResponse.getCode());
        	resultParam.put("msg", paymentResponse.getMsg());
        	resultParam.put("orderNum",paymentResponse.getOrderNumber());
            //流水状态
        	resultParam.put("status", "D2");
        	resultParam.put("payChannel", paymentResponse.getChannel());
        }
		return resultParam;
	}

	@Override
	public AmountDTO prePayTrail(String loanId) throws MarvelsBusinessException {
		//总金额
        BigDecimal amount = BigDecimal.ZERO;
        //提前结清费
        BigDecimal preFee = BigDecimal.ZERO;
        //提前结清本金利息管理费
        BigDecimal otherFee = BigDecimal.ZERO;
        if(loanId == null) {
            throw new MarvelsBusinessException("贷款编号为空!");
        }
        McfeCustomerLoanContractDTO contractDto =mcfeCustomerLoanContractDao.selectContractByLoanId(loanId);
        if(contractDto == null) { 
            throw new MarvelsBusinessException("贷款编号---"+loanId+"----对应的合同信息不存在!");
        }
        if(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_NORMAL!=contractDto.getStatus()
                && MarvelsConstant.CONTRACT_ACCOUNT_STATUS_DELQ!=contractDto.getStatus()) {
            throw new MarvelsBusinessException("贷款编号---"+loanId+"----对应的合同信息状态不正确!");
        }
        McptProduct productDtO = new  McptProduct();
        McptPreTerminationFeeDTO preTerminationFeeDTO = null;
        McptAmortMethodDTO amortMethodDTO = null;
        productDtO.setProductCode(contractDto.getProductCode());
        MarvelsResultDTO prePayTrailDto = iProductInfoApi.queryPrePayTrailMsg(productDtO);
        if (MarvelsErrorCode.SUCCESS.getValue().equals(prePayTrailDto.getCode())) {
        	String josnStr = JSON.toJSONString(prePayTrailDto.getData());
        	ProductMsgInfoDTO productMsgDtO  = JSON.toJavaObject(JSON.parseObject(josnStr), ProductMsgInfoDTO.class);
        	productDtO = productMsgDtO.getMcptProduct();//产品小类
        	preTerminationFeeDTO = productMsgDtO.getMcptPreTerminationFeeDTO();//提前结清信息
        	amortMethodDTO = productMsgDtO.getMcptAmortMethodDTO();//还款方式
        	if(productDtO == null) {
                throw new MarvelsBusinessException("贷款编号---"+loanId+"----对应的产品信息不存在！");
            }
        	if(preTerminationFeeDTO == null){
        		throw new MarvelsBusinessException("贷款编号---"+loanId+"----对应的提前结清费用信息不存在！！");
        	}
        	if(amortMethodDTO == null){
        		throw new MarvelsBusinessException("贷款编号---"+loanId+"----对应的还款方式信息不存在！！");
        	}
        	//获取提前结清前需完成的期数
            int requiredTenors = preTerminationFeeDTO.getRequiredTerms();
            if(contractDto.getCurrTenor() < requiredTenors ) {
            	throw new MarvelsBusinessException("贷款编号---"+loanId+"----不满足提前结清条件！！");
            }
            // 设置进位方式
            int roundFlag = 0;
            if (amortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_HALF_UP) {
                roundFlag = BigDecimal.ROUND_HALF_UP;
            } else if (amortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_UP) {
                roundFlag = BigDecimal.ROUND_UP;
            } else if (amortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_DOWN) {
                roundFlag = BigDecimal.ROUND_DOWN;
            }
            List<McfeCustomerRepaymentPlanDTO> normalPlan = mcfeCustomerRepaymentPlanDao.selectPlanByStatus(loanId, "0");//查询所有正常的还款计划
            List<McfeCustomerRepaymentPlanDTO> delqPlan = mcfeCustomerRepaymentPlanDao.selectPlanByStatus(loanId, "1");//查询所有逾期的还款计划
            McfeCustomerRepaymentPlanDTO firstNormalPlan = null;
            if(delqPlan!=null&&delqPlan.size()>0){
            	for(McfeCustomerRepaymentPlanDTO delqDtp:delqPlan){
            		otherFee = otherFee.add(delqDtp.getPrincipal()).subtract(delqDtp.getPrincipalAct()).add(delqDtp.getInterest())
            				.subtract(delqDtp.getInterestAct()).add(delqDtp.getManagementFee()).subtract(delqDtp.getManagementFeeAct())
            				.add(delqDtp.getPenaltyFee()).add(delqDtp.getPenaltyFeeAct()).add(delqDtp.getLateFee()).subtract(delqDtp.getLateFeeAct());
            	}
            	otherFee = otherFee.setScale(amortMethodDTO.getRoundDigit(), roundFlag);
            }
            if(normalPlan!=null&&normalPlan.size()>0){
            	firstNormalPlan = normalPlan.get(0);//按期数获取第一个正常的还款计划           	
            	preFee = preTrial(contractDto,preTerminationFeeDTO,normalPlan,amortMethodDTO.getRoundDigit(),roundFlag);//计算提前结清费
            	normalPlan.remove(0);//剔除第一个
            	BigDecimal fee = preTrialSumAmount(preTerminationFeeDTO,firstNormalPlan,amortMethodDTO.getRoundDigit(),roundFlag,normalPlan);//计算其他费用总和
            	otherFee = otherFee.add(fee);
            }
        }else{
        	throw new MarvelsBusinessException("调用远程产品小类查询接口失败");
        }
        amount =  preFee.add(otherFee);
        AmountDTO amountDto = new AmountDTO();
        amountDto.setPreAmount(amount);
        amountDto.setPreFee(preFee);
		return amountDto;
	}
	
	
	/**计算提前结清费
	 * @author 娄凯琦
	 * @date 2018年5月22日  
	 * @return
	 */
	private	BigDecimal preTrial(McfeCustomerLoanContractDTO contract, McptPreTerminationFeeDTO preTerminationFee,List<McfeCustomerRepaymentPlanDTO> delqPlans,
            int roundDigits,int roundFlag){
		BigDecimal amount = BigDecimal.ZERO.setScale(2);
	    BigDecimal preFee = BigDecimal.ZERO.setScale(2);
	    //应计算费用的金额
        BigDecimal duePrincial = BigDecimal.ZERO;
        //正常还款计划本金之和
        BigDecimal normalPrincial = BigDecimal.ZERO;
        for(McfeCustomerRepaymentPlanDTO planDto:delqPlans) {
        	normalPrincial = normalPrincial.add(planDto.getPrincipal()).subtract(planDto.getPrincipalWaive());
        }
        //剩余本金(剩余未还本金-逾期本金)
        if(MarvelsConstant.PRINCIAL_TYPE_HAD.equals(preTerminationFee.getPrincipalType())) {
            duePrincial = normalPrincial;
        }
        //贷款金额
        else if(MarvelsConstant.PRINCIAL_TYPE_LOAN.equals(preTerminationFee.getPrincipalType())) {
            duePrincial = contract.getAmount().subtract(contract.getPrincipalWaive());
        }
        preFee = computemPreTerminationFee(preTerminationFee,duePrincial);//计算提前你结清费
	    amount = preFee.setScale(roundDigits,roundFlag);
		return amount;
	}
	
	
	
	/**
	 * 计算提前结清费
	 * 
	 * @param obj
	 * @param principal
	 * @return
	 */
	private BigDecimal computemPreTerminationFee(McptPreTerminationFeeDTO mcptPreTerminationFeeDTO, BigDecimal principal) {
		BigDecimal amount = BigDecimal.ZERO;
		if (principal.compareTo(BigDecimal.ZERO) == 0)
			return amount;
		// 获取费用收取方式
		String chargeMethod = mcptPreTerminationFeeDTO.getChargeMethod() + "";
		// 获取最小费用
		BigDecimal minFee = mcptPreTerminationFeeDTO.getMinFee();
		// 获取最大费用
		BigDecimal maxFee = mcptPreTerminationFeeDTO.getMaxFee();
		// 获取费用类型
		String feeType = mcptPreTerminationFeeDTO.getFeeType() + "";
		// 获取基础费用
		BigDecimal baseFee = mcptPreTerminationFeeDTO.getBaseFee();
		// 费用类型为固定金额
		if (MarvelsConstant.FEE_TYPE_FIXED.equalsIgnoreCase(feeType)) {
			amount = baseFee;
		}
		// 费用类型：百分比（变动）
		else if (MarvelsConstant.FEE_TYPE_VAR.equalsIgnoreCase(feeType)) {
			// 获取费用百分比
			BigDecimal percentage = mcptPreTerminationFeeDTO.getPercentage();
			// 计算金额
			amount = baseFee.add(principal.multiply(percentage));
		}
		// 费用类型：阶段
		else if (MarvelsConstant.FEE_TYPE_TIER.equalsIgnoreCase(feeType)) {
			// 获取阶段收取方式
			String tierFlag = mcptPreTerminationFeeDTO.getTierFlag() + "";
			// 获取各个阶段的阈值
			// 阶段1
			BigDecimal limit1 = BigDecimal.valueOf(mcptPreTerminationFeeDTO.getPhase1Limit());
			// 阶段2
			BigDecimal limit2 = BigDecimal.valueOf(mcptPreTerminationFeeDTO.getPhase2Limit());
			// 阶段方式：金额
			if (MarvelsConstant.FEE_TIER_AMOUNT.equalsIgnoreCase(tierFlag)) {
				// 获取各阶段金额
				BigDecimal amount1 = mcptPreTerminationFeeDTO.getPhase1Amount();
				BigDecimal amount2 = mcptPreTerminationFeeDTO.getPhase2Amount();
				BigDecimal amount3 = mcptPreTerminationFeeDTO.getPhase3Amount();
				// 大于阶段2阈值
				if (principal.compareTo(limit2) > 0) {
					amount = amount1.add(amount2).add(amount3);
				} else if (principal.compareTo(limit1) > 0) {
					amount = amount1.add(amount2);
				} else {
					amount = amount1;
				}
			}
			// 阶段方式：百分比
			else if (MarvelsConstant.FEE_TIER_PERCENTAGE.equalsIgnoreCase(tierFlag)) {
				// 获取3个阶段比例
				BigDecimal percen1 = mcptPreTerminationFeeDTO.getPhase1Percentage();
				BigDecimal percen2 = mcptPreTerminationFeeDTO.getPhase2Percentage();
				BigDecimal percen3 = mcptPreTerminationFeeDTO.getPhase3Percentage();
				// 先设三个阶段的费用
				// 3阶段需收费用
				BigDecimal amount3Act = BigDecimal.ZERO;
				// 2阶段需收费用
				BigDecimal amount2Act = BigDecimal.ZERO;
				// 1阶段需收费用
				BigDecimal amount1Act = BigDecimal.ZERO;
				if (principal.compareTo(limit2) > 0) {
					// 3阶段需收费用
					amount3Act = principal.subtract(limit2).multiply(percen3);
					// 2阶段需收费用
					amount2Act = limit2.subtract(limit1).multiply(percen2);
					// 1阶段需收费用
					amount1Act = limit1.multiply(percen1);
				} else if (principal.compareTo(limit1) > 0) {
					amount2Act = principal.subtract(limit1).multiply(percen2);
					amount1Act = limit1.multiply(percen1);
				} else {
					amount1Act = principal.multiply(percen1);
				}
				amount = amount1Act.add(amount2Act).add(amount3Act);
			}
			amount = amount.add(baseFee);
		}
		// 与最小费用和最大费用比较
		if (amount.compareTo(minFee) < 0) {
			amount = minFee;
		}
		if (amount.compareTo(maxFee) > 0) {
			amount = maxFee;
		}
		
		return amount;
	}
	
	
	
	/**计算其他费用总和(不包括提前结清费)
	 * @author 娄凯琦
	 * @date 2018年5月22日  
	 * @param preTerminationFee
	 * @param nextMp
	 * @param roundDigits
	 * @param roundFlag
	 * @param normalList
	 * @return
	 */
	private  BigDecimal preTrialSumAmount(McptPreTerminationFeeDTO preTerminationFee,McfeCustomerRepaymentPlanDTO nextMp, int roundDigits,int roundFlag,List<McfeCustomerRepaymentPlanDTO> normalList){
    	//提前结清总金额
    	BigDecimal amount = BigDecimal.ZERO.setScale(2);
    	for(McfeCustomerRepaymentPlanDTO normalDto:normalList){
    		amount = amount.add(normalDto.getPrincipal()).subtract(normalDto.getPrincipalWaive());
    	}
    	if(nextMp!=null){
    		Calendar ca = Calendar.getInstance();
			ca.add(Calendar.MONTH, 1);
    		if(ca.getTime().compareTo(nextMp.getPaymentDateLate())<=0){
    			amount = amount.add(nextMp.getPrincipal()).subtract(nextMp.getPrincipalWaive());
			}else{
				amount = amount.add(nextMp.getManagementFee()).add(nextMp.getPrincipal()).add(nextMp.getInterest()).subtract(nextMp.getManagementFeeWaive())
						.subtract(nextMp.getPrincipalWaive()).subtract(nextMp.getInterestWaive());
			}
    	}
    	if(MarvelsConstant.BALANCE_CHARGE_METHOD_DEFAULT.equals(preTerminationFee.getBalanceChargeMethod())){
    		//1、收手续费+本期费用；
    	}else if(MarvelsConstant.BALANCE_CHARGE_METHOD_INST.equals(preTerminationFee.getBalanceChargeMethod())){
    		//2、收手续费+本期费用+剩余利息；
//    		amount = amount.add(contract.getInterestOs());
    	}else if(MarvelsConstant.BALANCE_CHARGE_METHOD_INST_FEE2.equals(preTerminationFee.getBalanceChargeMethod())){
    		//3、收手续费+本期费用+剩余利息+剩余管理费；
//    		amount = amount.add(contract.getInterestOs()).add(contract.getFeeOs().subtract(PenaltyFee).subtract(currFee));
    	}	
    	return amount.setScale(roundDigits,roundFlag);
    }

	@Override
	public BigDecimal queryCurrentTenorMoney(String loanId) throws MarvelsBusinessException {
		BigDecimal currentMoney = BigDecimal.ZERO;
		if(StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())) {
			currentMoney = mcfeCustomerRepaymentPlanDao.newSelectCurrentTenorMoney(loanId);
		}else {
			currentMoney = mcfeCustomerRepaymentPlanDao.selectCurrentTenorMoney(loanId);//查询当期应还金额
		}
		return currentMoney;
	}

	@Override
	public BigDecimal queryRepaymentAllMoney(String loanId) throws MarvelsBusinessException {
		BigDecimal currentMoney = mcfeCustomerRepaymentPlanDao.selectCurrentTenorMoney(loanId);//查询当期应还金额
		return currentMoney;
	}	
	
	@Override
	public BigDecimal queryNextTenorMoney(String loanId) throws MarvelsBusinessException {
		return mcfeCustomerRepaymentPlanDao.selectNextTenorMoney(loanId);//查询下期应还金额
	}


	@Override//冲账
	@Transactional(rollbackFor=Exception.class)
	public void StrikeBalance(McfeRepaymentFlowDTO mcfeRepaymentFlowDTO) throws MarvelsBusinessException {
		if(mcfeRepaymentFlowDTO == null){
			throw new MarvelsBusinessException("传入参数为空");
		}
		MarvelsLogUtil.getInstance().info("the StrikeBalance repaymentFlow  Start"+JSON.toJSONString(mcfeRepaymentFlowDTO));
		BigDecimal amountAct = mcfeRepaymentFlowDTO.getAmountAct();//实还金额
		if(amountAct!=null&&amountAct.compareTo(BigDecimal.ZERO)==0){
			return;
		}
		McfeCustomerLoanContractDTO contract = mcfeCustomerLoanContractDao.selectContractByLoanId(mcfeRepaymentFlowDTO.getLoanId());//合同信息
		if(contract==null){
			throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----对应的合同信息不存在！");
		}
		paymentLogic(mcfeRepaymentFlowDTO,contract);//冲账逻辑
		mcfeRepaymentFlowDao.updateStatusById(mcfeRepaymentFlowDTO.getId(), "2");//更新还款流水表状态为A2
		//更新ac_trace状态为正常结清
		SynLoanStatus2ApplyDTO synLoanStatus2ApplyDTO = new SynLoanStatus2ApplyDTO();
		synLoanStatus2ApplyDTO.setLoanId(mcfeRepaymentFlowDTO.getLoanId());
		synLoanStatus2ApplyDTO.setOriginalState(LoanStateConstant.D01);
		
		MarvelsLogUtil.getInstance().info("the method paymentStrikeBalance contract=========="+JSON.toJSONString(contract));
		if(contract.getStatus().toString().equals("2")){//结清
			synLoanStatus2ApplyDTO.setStatus(LoanStateConstant.A00);
			iLoanApplyMqProduct.synLoanStatus2Apply(synLoanStatus2ApplyDTO);
		}
	}
	
	private void prepayLogic(McfeRepaymentFlowDTO mcfeRepaymentFlowDTO,McfeCustomerLoanContractDTO contract) throws MarvelsBusinessException{
		McfeCustomerLoanInfoDTO customerLoanInfoDTO = mcfeCustomerLoanInfoDao.selectCustomerLoanInfoByLoanId(mcfeRepaymentFlowDTO.getLoanId());
		if(customerLoanInfoDTO==null){
			throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----对应的客户贷款信息不存在！");
		}
		McptProduct dto = new McptProduct();
		List<McptPaymentSequenceItemDTO> sequenceList= null;
		McptAmortMethodDTO amortMethodDTO  = null;
		McptPreTerminationFeeDTO mcptPreTerminationFeeDTO = null;
		dto.setProductCode(contract.getProductCode());
		MarvelsResultDTO resultDTO = iProductInfoApi.queryStrikeBalanceMsg(dto);//查询产品小类信息
		if(MarvelsErrorCode.SUCCESS.getValue().equals(resultDTO.getCode())){
			String josnStr = JSON.toJSONString(resultDTO.getData());
			ProductMsgInfoDTO productMsgInfoDTO = JSON.toJavaObject(JSON.parseObject(josnStr), ProductMsgInfoDTO.class);
			dto = productMsgInfoDTO.getMcptProduct();
			sequenceList = productMsgInfoDTO.getMcptPaymentSequenceItemDTO();
			amortMethodDTO = productMsgInfoDTO.getMcptAmortMethodDTO();
			mcptPreTerminationFeeDTO = productMsgInfoDTO.getMcptPreTerminationFeeDTO();
			if(dto==null){
				throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----对应的产品信息不存在！");
			}
			if(sequenceList==null){
				throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----对应的还款顺序不存在！");
			}
			if(mcptPreTerminationFeeDTO==null){
				throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----对应的提前结清费信息不存在！");
			}
			if(amortMethodDTO==null){
				throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----对应的还款方式信息不存在！");
			}
		}else{
			throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----远程查询产品冲账信息失败！");
		}
		// 设置进位方式
        int roundFlag = 0;
        if (amortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_HALF_UP) {
            roundFlag = BigDecimal.ROUND_HALF_UP;
        } else if (amortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_UP) {
            roundFlag = BigDecimal.ROUND_UP;
        } else if (amortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_DOWN) {
            roundFlag = BigDecimal.ROUND_DOWN;
        }
        updatePlanContract(mcfeRepaymentFlowDTO,contract,customerLoanInfoDTO);//计算提前结清费和其他费用,更新还款计划和合同
        
        List<McfeCustomerRepaymentPlanDTO> unCompletedPlan = mcfeCustomerRepaymentPlanDao.selectAllUncompletedPlan(mcfeRepaymentFlowDTO.getLoanId());
        boolean mark = true;
        BigDecimal amountAct = mcfeRepaymentFlowDTO.getAmountAct();
        String updateBy="";
    	String createdBy="";
    	UserDTO userDTO=null;
    	try{
    		userDTO=CacheUtils.getCacheUser();
    	}catch(Exception e){
    		MarvelsLogUtil.getInstance().error(">>>>>>>>获取当前信息异常:",e);
    	}
    	if(userDTO==null){
    		updateBy="system";
    		createdBy="system";
    	}else{
    		updateBy=userDTO.getUserCode();
    		createdBy=userDTO.getUserCode();
    	}
        for(McfeCustomerRepaymentPlanDTO plan:unCompletedPlan){
        	List<McfeReversalDetailDTO> reversalList= new ArrayList<McfeReversalDetailDTO>();//各费用冲账明细
        	Map<String,BigDecimal> amountMap= updateLoanPlan(amountAct,sequenceList,plan,mcfeRepaymentFlowDTO,mcfeRepaymentFlowDTO.getCreatedDate(),reversalList);//冲账后剩余金额与冲账明细
        	if(plan.getDelqDays()==0&&plan.getStatus()==2){
        		plan.setStatus(3);
        	}
        	plan.setUpdatedBy(updateBy);
        	mcfeCustomerRepaymentPlanDao.updateRepaymentPlanById(plan);
        	if(reversalList.size()>0){
    			mcfeReversalDetailDao.insertReversalDetails(reversalList);//保存冲账明细
    		}
            BigDecimal needAmount = plan.getPrincipal().subtract(plan.getPrincipalAct()).add(plan.getInterest()).subtract(plan.getInterestAct())
            		.add(plan.getManagementFee()).subtract(plan.getManagementFeeAct()).add(plan.getPenaltyFee()).subtract(plan.getPenaltyFeeAct())
            		.add(plan.getLateFee()).subtract(plan.getLateFeeAct()).add(plan.getPlatformFee()).subtract(plan.getPlatformFeeAct())
            		.add(plan.getMiscFee()).subtract(plan.getMiscFeeAct()).subtract(plan.getPrincipalWaive()).subtract(plan.getInterestWaive())
            		.subtract(plan.getConsultingFeeWaive()).subtract(plan.getManagementFeeWaive()).subtract(plan.getPenaltyFeeWaive()).subtract(plan.getLateFeeWaive())
            		.subtract(plan.getPreTerminateFeeWaive());//需要减去减免金额
        	updateContractInfo(contract,plan,mcfeRepaymentFlowDTO.getCreatedDate(),amountMap,needAmount);//更新合同信息
    		
        	updateCustomerLoanInfo(customerLoanInfoDTO,plan,mcfeRepaymentFlowDTO.getCreatedDate(),amountMap,needAmount,contract);//贷款信息表
    	   		
    		if(plan.getStatus()!=3){//还款计划状态不为体检结清
    			mark = false;
    		}
    		//保存冲销还款计划流水
    		McfeReversalFlowDTO mcfeReversalFlowDTO = new McfeReversalFlowDTO();
    		mcfeReversalFlowDTO.setCustCardNo(mcfeRepaymentFlowDTO.getCustCardNo());
    		mcfeReversalFlowDTO.setCustName(mcfeRepaymentFlowDTO.getCustName());
    		mcfeReversalFlowDTO.setMobile(mcfeRepaymentFlowDTO.getMobile());
    		mcfeReversalFlowDTO.setLoanId(mcfeRepaymentFlowDTO.getLoanId());
    		mcfeReversalFlowDTO.setBankCardNo(mcfeRepaymentFlowDTO.getBankCardNo());
    		mcfeReversalFlowDTO.setBankName(mcfeRepaymentFlowDTO.getBankName());
    		mcfeReversalFlowDTO.setBankHeadLink(mcfeRepaymentFlowDTO.getBankHeadLink());
    		mcfeReversalFlowDTO.setTransctionSeq(mcfeRepaymentFlowDTO.getTransctionSeq());
    		mcfeReversalFlowDTO.setRtnOrderNo(mcfeRepaymentFlowDTO.getRtnOrderNo());
    		mcfeReversalFlowDTO.setReqChannel(mcfeRepaymentFlowDTO.getReqChannel());
    		mcfeReversalFlowDTO.setResChannel(mcfeRepaymentFlowDTO.getResChannel());
    		mcfeReversalFlowDTO.setGroupEng(mcfeRepaymentFlowDTO.getGroupEng());
    		mcfeReversalFlowDTO.setFundCode(mcfeRepaymentFlowDTO.getFundCode());
    		mcfeReversalFlowDTO.setFundName(mcfeRepaymentFlowDTO.getFundName());
    		mcfeReversalFlowDTO.setProductType(mcfeRepaymentFlowDTO.getProductType());
    		mcfeReversalFlowDTO.setProductTypeName(mcfeRepaymentFlowDTO.getProductTypeName());
    		mcfeReversalFlowDTO.setProductCode(mcfeRepaymentFlowDTO.getProductCode());
    		mcfeReversalFlowDTO.setProductName(mcfeRepaymentFlowDTO.getProductName());
    		mcfeReversalFlowDTO.setChannelCode(mcfeRepaymentFlowDTO.getChannelCode());
    		mcfeReversalFlowDTO.setChannelName(mcfeRepaymentFlowDTO.getChannelName());
    		mcfeReversalFlowDTO.setTenor(plan.getTenor());
    		mcfeReversalFlowDTO.setPaymentDate(plan.getPaymentDateLate());
    		mcfeReversalFlowDTO.setPaymentDateAct(plan.getPaymentDateAct());
    		mcfeReversalFlowDTO.setPlanCode(plan.getPlanCode());
    		mcfeReversalFlowDTO.setDelqDays(plan.getDelqDays());
    		mcfeReversalFlowDTO.setPayType(mcfeRepaymentFlowDTO.getPayType());
    		mcfeReversalFlowDTO.setRepaymentType(plan.getRepaymentType());
    		mcfeReversalFlowDTO.setPrincipalAct(amountMap.get("principal"));
    		mcfeReversalFlowDTO.setInterestAct(amountMap.get("interest"));
    		mcfeReversalFlowDTO.setConsultingFeeAct(amountMap.get("consultingFee"));
    		mcfeReversalFlowDTO.setManagementFeeAct(amountMap.get("managementFee"));
    		mcfeReversalFlowDTO.setPenaltyFeeAct(amountMap.get("penaltyFee"));
    		mcfeReversalFlowDTO.setLateFeeAct(amountMap.get("lateFee"));
    		mcfeReversalFlowDTO.setPreTerminateFeeAct(amountMap.get("preterminateFee"));
    		mcfeReversalFlowDTO.setMiscFeeAct(amountMap.get("miscFee"));
    		mcfeReversalFlowDTO.setPlatformFeeAct(amountMap.get("platformFee"));
    		mcfeReversalFlowDTO.setRiskFeeAct(amountMap.get("riskFee"));
//    		mcfeReversalFlowDTO.setRemark();
//    		mcfeReversalFlowDTO.setDeleteFlag();
    		mcfeReversalFlowDTO.setCreatedBy(createdBy);
    		mcfeReversalFlowDTO.setUpdatedBy(updateBy);
    		mcfeReversalFlowDao.insertReversalFlow(mcfeReversalFlowDTO);
    		amountAct = amountMap.get("amount");
    		if(amountAct.compareTo(BigDecimal.ZERO)!=1){
    			break;
    		}
        }
        if(mark){
        	contract.setStatus(3);
        	contract.setDelqDays(0);
        	contract.setCurrTenor(contract.getTenor());
        	customerLoanInfoDTO.setStatus(contract.getStatus());
        }
        contract.setUpdatedBy(updateBy);
        mcfeCustomerLoanContractDao.updateContractById(contract);
        customerLoanInfoDTO.setUpdatedBy(updateBy);
        mcfeCustomerLoanInfoDao.updateCustomerLoanInfoById(customerLoanInfoDTO);
		
		//
		
	}
	/**更新还款计划和合同
	 * @author 娄凯琦
	 * @throws MarvelsBusinessException 
	 * @date 2018年5月28日  
	 */
	private void updatePlanContract(McfeRepaymentFlowDTO mcfeRepaymentFlowDTO,McfeCustomerLoanContractDTO contract,McfeCustomerLoanInfoDTO customerLoanInfoDTO) throws MarvelsBusinessException{
		List<McfeCustomerRepaymentPlanDTO> planList = mcfeCustomerRepaymentPlanDao.selectAllNormalPlan(mcfeRepaymentFlowDTO.getLoanId());
        Date createDate =mcfeRepaymentFlowDTO.getCreatedDate();
        Calendar ca = Calendar.getInstance();
        ca.setTime(createDate);
        ca.add(Calendar.MONTH, 1);
        String createdBy="";
		String updateBy="";
		UserDTO userDTO=null;
		try{
			userDTO=CacheUtils.getCacheUser();
		}catch(Exception e){
			MarvelsLogUtil.getInstance().error(">>>>>>>>>获取当前用户信息异常:",e);
		}
		if(userDTO==null){
			createdBy="system";
			updateBy="system";
		}else{
			createdBy=userDTO.getUserCode();
			updateBy=userDTO.getUserCode();
		}
        if(planList!=null&&planList.size()>0){
        	McfeCustomerRepaymentPlanDTO lastPlan = planList.get(planList.size()-1);
        	MarvelsLogUtil.getInstance().info("the lastPlan status ==="+lastPlan.getStatus()+""
        			+ "----------loanId"+planList.get(0).getLoanId()+"---plan_id:"+planList.get(0).getPlanCode()+"---------paymentDateLate:"+
        			planList.get(0).getPaymentDateLate());
        	if(0==lastPlan.getStatus()){
        		AmountDTO amountDto = prePayTrail(mcfeRepaymentFlowDTO.getLoanId());
        		BigDecimal preTerminateFee = amountDto.getPreFee();
	        	if(planList.get(0).getPaymentDateLate().compareTo(ca.getTime())==-1&&planList.size()>1){
	        		MarvelsLogUtil.getInstance().info("to enter one");
	        		planList.remove(0);
	        		McfeCustomerRepaymentPlanDTO tmpPlan = planList.get(0);
	        		for(McfeCustomerRepaymentPlanDTO plan: planList){
	        			if(tmpPlan.getTenor()!=plan.getTenor()){
	        				tmpPlan.setPrincipal(tmpPlan.getPrincipal().add(plan.getPrincipal()));
	        			}
	        			mcfeCustomerRepaymentPlanDao.deletePlanById(plan);
	        			plan.setCreatedBy(createdBy);
	        			plan.setUpdatedBy(updateBy);
	        			mcfeCustomerRepaymentPlanLogDao.insertRepaymentPlanLog(plan);
	        			contract.setInterestOs(contract.getInterestOs().subtract(plan.getInterest()));
	        			contract.setManagementFeeOs(contract.getManagementFeeOs().subtract(plan.getManagementFee()));
	        			customerLoanInfoDTO.setInterestOs(customerLoanInfoDTO.getInterestOs().subtract(plan.getInterest()));
	        			customerLoanInfoDTO.setManagementFeeOs(customerLoanInfoDTO.getManagementFeeOs().subtract(plan.getManagementFee()));
	        		}
	        		contract.setPreTerminateFeeOs(preTerminateFee);
	        		tmpPlan.setInterest(BigDecimal.ZERO);
	        		tmpPlan.setManagementFee(BigDecimal.ZERO);
	        		tmpPlan.setPreTerminateFee(preTerminateFee);
	        		tmpPlan.setStatus(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_MIDDLE);//更新为提前结清分期冲账中间状态
	        		tmpPlan.setCreatedBy(createdBy);
	        		tmpPlan.setUpdatedBy(updateBy);
	        		mcfeCustomerRepaymentPlanDao.insertRepaymentPlan(tmpPlan);
	        	}else if(planList.get(0).getPaymentDateLate().compareTo(ca.getTime())==-1&&planList.size()==1){
	        		MarvelsLogUtil.getInstance().info("to enter two");
	        		lastPlan.setStatus(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_MIDDLE);
	        		lastPlan.setPreTerminateFee(preTerminateFee);
	        		lastPlan.setUpdatedBy(updateBy);
	        		mcfeCustomerRepaymentPlanDao.updateRepaymentPlanById(lastPlan);
	        	}else if(planList.get(0).getPaymentDateLate().compareTo(ca.getTime())>=0&&planList.size()==1){
	        		MarvelsLogUtil.getInstance().info("to enter three");
	        		lastPlan.setStatus(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_MIDDLE);//更新为提前结清分期冲账中间状态
	        		lastPlan.setPreTerminateFee(preTerminateFee);
	        		lastPlan.setManagementFee(BigDecimal.ZERO);
	        		lastPlan.setInterest(BigDecimal.ZERO);
	        		contract.setInterestOs(contract.getInterestOs().subtract(lastPlan.getInterest().subtract(lastPlan.getInterestAct())));
        			contract.setManagementFeeOs(contract.getManagementFeeOs().subtract(lastPlan.getManagementFee().subtract(lastPlan.getManagementFeeAct())));
        			contract.setPreTerminateFeeOs(preTerminateFee);
        			customerLoanInfoDTO.setInterestOs(customerLoanInfoDTO.getInterestOs().subtract(lastPlan.getInterest()));
        			customerLoanInfoDTO.setManagementFeeOs(customerLoanInfoDTO.getManagementFeeOs().subtract(lastPlan.getManagementFee()));
	        		mcfeCustomerRepaymentPlanDao.updateRepaymentPlanById(lastPlan);
	        	}
	        	else if(planList.get(0).getPaymentDateLate().compareTo(ca.getTime())>=0&&planList.size()>1){
	        		MarvelsLogUtil.getInstance().info("to enter four");
	        		McfeCustomerRepaymentPlanDTO tmpPlan = planList.get(0);
	        		for(McfeCustomerRepaymentPlanDTO plan: planList){
	        			if(tmpPlan.getTenor()!=plan.getTenor()){
	        				tmpPlan.setPrincipal(tmpPlan.getPrincipal().add(plan.getPrincipal()));
	        			}
	        			mcfeCustomerRepaymentPlanDao.deletePlanById(plan);
	        			mcfeCustomerRepaymentPlanLogDao.insertRepaymentPlanLog(plan);
	        			contract.setInterestOs(contract.getInterestOs().subtract(plan.getInterest()));
	        			contract.setManagementFeeOs(contract.getManagementFeeOs().subtract(plan.getManagementFee()));
	        			customerLoanInfoDTO.setInterestOs(customerLoanInfoDTO.getInterestOs().subtract(plan.getInterest()));
	        			customerLoanInfoDTO.setManagementFeeOs(customerLoanInfoDTO.getManagementFeeOs().subtract(plan.getManagementFee()));
	        		}
	        		contract.setPreTerminateFeeOs(preTerminateFee);
	        		tmpPlan.setInterest(BigDecimal.ZERO);
	        		tmpPlan.setManagementFee(BigDecimal.ZERO);
	        		tmpPlan.setPreTerminateFee(preTerminateFee);
	        		tmpPlan.setStatus(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_MIDDLE);//更新为提前结清分期冲账中间状态
	        		mcfeCustomerRepaymentPlanDao.insertRepaymentPlan(tmpPlan);
	        	}
        	}
        }
	}
	/**普通还款冲账逻辑
	 * @author 娄凯琦
	 * @date 2018年5月23日  
	 * @param amount
	 * @param plan
	 * @param mcfeRepaymentFlowDTO
	 */
	private void paymentLogic(McfeRepaymentFlowDTO mcfeRepaymentFlowDTO,McfeCustomerLoanContractDTO contract) throws MarvelsBusinessException {
		BigDecimal amount = mcfeRepaymentFlowDTO.getAmountAct();
		//查询所有未完成还款计划
		List<McfeCustomerRepaymentPlanDTO> planList = mcfeCustomerRepaymentPlanDao.selectAllUncompletedPlan(mcfeRepaymentFlowDTO.getLoanId());
		
		if(planList==null||planList.size()==0){
			throw new MarvelsBusinessException("根据loanId===="+mcfeRepaymentFlowDTO.getLoanId()+"----查询还款计划异常");
		}
		
		McfeCustomerLoanInfoDTO CustomerLoanInfoDTO = mcfeCustomerLoanInfoDao.selectCustomerLoanInfoByIdNumber(contract.getCustCardNo());
		if(CustomerLoanInfoDTO==null){
			throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----对应的客户贷款信息不存在！");
		}
		McptProduct dto = new McptProduct();
		List<McptPaymentSequenceItemDTO> sequenceList= null;
		dto.setProductCode(contract.getProductCode());
		MarvelsResultDTO resultDTO = iProductInfoApi.queryStrikeBalanceMsg(dto);//查询产品小类信息
		if(MarvelsErrorCode.SUCCESS.getValue().equals(resultDTO.getCode())){
			String josnStr = JSON.toJSONString(resultDTO.getData());
			ProductMsgInfoDTO productMsgInfoDTO = JSON.toJavaObject(JSON.parseObject(josnStr), ProductMsgInfoDTO.class);
			dto = productMsgInfoDTO.getMcptProduct();
			sequenceList = productMsgInfoDTO.getMcptPaymentSequenceItemDTO();
			if(dto==null){
				throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----对应的产品信息不存在！");
			}
			if(sequenceList==null){
				throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----对应的还款顺序不存在！");
			}
		}else{
			throw new MarvelsBusinessException("loanId:" + mcfeRepaymentFlowDTO.getLoanId() + "----远程查询产品冲账信息失败！");
		}
		Date date = new Date();
		//更新还款计划表
		String updateBy="";
		String createBy="";
    	UserDTO userDTO=null;
    	try{
    		userDTO=CacheUtils.getCacheUser();
    	}catch(Exception e){
    		MarvelsLogUtil.getInstance().error(">>>>>>>>获取当前信息异常:",e);
    	}
    	if(userDTO==null){
    		updateBy="system";
    		createBy="system";
    	}else{
    		updateBy=userDTO.getUserCode();
    		createBy=userDTO.getUserCode();
    	}
		//更新还款计划
		for(McfeCustomerRepaymentPlanDTO plan:planList){
			if(amount.compareTo(BigDecimal.ZERO)==0){
				break;
			}
			List<McfeReversalDetailDTO> reversalList= new ArrayList<McfeReversalDetailDTO>();//各费用冲账明细
			Map<String,BigDecimal> amountMap= updateLoanPlan(amount,sequenceList,plan,mcfeRepaymentFlowDTO,date,reversalList);//冲账后剩余金额与冲账明细
			MarvelsLogUtil.getInstance().info(">>>>>>>>>冲账金额信息:"+JSONObject.fromObject(amountMap)+",reversalList.size:"+reversalList.size());
			if(reversalList.size()>0){
				mcfeReversalDetailDao.insertReversalDetails(reversalList);//保存冲账明细
			}
        	plan.setUpdatedBy(updateBy);
			mcfeCustomerRepaymentPlanDao.updateRepaymentPlanById(plan);
	        BigDecimal needAmount = plan.getPrincipal().subtract(plan.getPrincipalAct()).add(plan.getInterest()).subtract(plan.getInterestAct())
	        		.add(plan.getManagementFee()).subtract(plan.getManagementFeeAct()).add(plan.getPenaltyFee()).subtract(plan.getPenaltyFeeAct())
	        		.add(plan.getLateFee()).subtract(plan.getLateFeeAct()).add(plan.getPlatformFee()).subtract(plan.getPlatformFeeAct())
	        		.add(plan.getMiscFee()).subtract(plan.getMiscFeeAct()).subtract(plan.getPrincipalWaive()).subtract(plan.getInterestWaive())
	        		.subtract(plan.getConsultingFeeWaive()).subtract(plan.getManagementFeeWaive()).subtract(plan.getPenaltyFeeWaive()).subtract(plan.getLateFeeWaive())
	        		.subtract(plan.getPreTerminateFeeWaive());//冲账后该笔还款计划需还金额   需要减掉减免金额
			updateContractInfo(contract,plan,date,amountMap,needAmount);//更新合同信息
			updateCustomerLoanInfo(CustomerLoanInfoDTO,plan,date,amountMap,needAmount,contract);//贷款信息表
			contract.setUpdatedBy(updateBy);
			mcfeCustomerLoanContractDao.updateContractById(contract);
			mcfeCustomerLoanInfoDao.updateCustomerLoanInfoById(CustomerLoanInfoDTO);
			//保存冲销还款计划流水
			McfeReversalFlowDTO mcfeReversalFlowDTO = new McfeReversalFlowDTO();
			mcfeReversalFlowDTO.setCustCardNo(mcfeRepaymentFlowDTO.getCustCardNo());
			mcfeReversalFlowDTO.setCustName(mcfeRepaymentFlowDTO.getCustName());
			mcfeReversalFlowDTO.setMobile(mcfeRepaymentFlowDTO.getMobile());
			mcfeReversalFlowDTO.setLoanId(mcfeRepaymentFlowDTO.getLoanId());
			mcfeReversalFlowDTO.setBankCardNo(mcfeRepaymentFlowDTO.getBankCardNo());
			mcfeReversalFlowDTO.setBankName(mcfeRepaymentFlowDTO.getBankName());
			mcfeReversalFlowDTO.setBankHeadLink(mcfeRepaymentFlowDTO.getBankHeadLink());
			mcfeReversalFlowDTO.setTransctionSeq(mcfeRepaymentFlowDTO.getTransctionSeq());
			mcfeReversalFlowDTO.setRtnOrderNo(mcfeRepaymentFlowDTO.getRtnOrderNo());
			mcfeReversalFlowDTO.setReqChannel(mcfeRepaymentFlowDTO.getReqChannel());
			mcfeReversalFlowDTO.setResChannel(mcfeRepaymentFlowDTO.getResChannel());
			mcfeReversalFlowDTO.setGroupEng(mcfeRepaymentFlowDTO.getGroupEng());
			mcfeReversalFlowDTO.setFundCode(mcfeRepaymentFlowDTO.getFundCode());
			mcfeReversalFlowDTO.setFundName(mcfeRepaymentFlowDTO.getFundName());
			mcfeReversalFlowDTO.setProductType(mcfeRepaymentFlowDTO.getProductType());
			mcfeReversalFlowDTO.setProductTypeName(mcfeRepaymentFlowDTO.getProductTypeName());
			mcfeReversalFlowDTO.setProductCode(mcfeRepaymentFlowDTO.getProductCode());
			mcfeReversalFlowDTO.setProductName(mcfeRepaymentFlowDTO.getProductName());
			mcfeReversalFlowDTO.setChannelCode(mcfeRepaymentFlowDTO.getChannelCode());
			mcfeReversalFlowDTO.setChannelName(mcfeRepaymentFlowDTO.getChannelName());
			mcfeReversalFlowDTO.setTenor(plan.getTenor());
			mcfeReversalFlowDTO.setPaymentDate(plan.getPaymentDateLate());
			mcfeReversalFlowDTO.setPaymentDateAct(plan.getPaymentDateAct());
			mcfeReversalFlowDTO.setPlanCode(plan.getPlanCode());
			mcfeReversalFlowDTO.setDelqDays(plan.getDelqDays());
			mcfeReversalFlowDTO.setPayType(mcfeRepaymentFlowDTO.getPayType());
			mcfeReversalFlowDTO.setRepaymentType(plan.getRepaymentType());
			mcfeReversalFlowDTO.setPrincipalAct(amountMap.get("principal"));
			mcfeReversalFlowDTO.setInterestAct(amountMap.get("interest"));
			mcfeReversalFlowDTO.setConsultingFeeAct(amountMap.get("consultingFee"));
			mcfeReversalFlowDTO.setManagementFeeAct(amountMap.get("managementFee"));
			mcfeReversalFlowDTO.setPenaltyFeeAct(amountMap.get("penaltyFee"));
			mcfeReversalFlowDTO.setLateFeeAct(amountMap.get("lateFee"));
			mcfeReversalFlowDTO.setPreTerminateFeeAct(amountMap.get("preterminateFee"));
			mcfeReversalFlowDTO.setMiscFeeAct(amountMap.get("miscFee"));
			mcfeReversalFlowDTO.setPlatformFeeAct(amountMap.get("platformFee"));
			mcfeReversalFlowDTO.setRiskFeeAct(amountMap.get("riskFee"));
	//		mcfeReversalFlowDTO.setRemark();
	//		mcfeReversalFlowDTO.setDeleteFlag();
			mcfeReversalFlowDTO.setCreatedBy(createBy);
			mcfeReversalFlowDTO.setUpdatedBy(updateBy);
			MarvelsLogUtil.getInstance().info("the mcfeReversalFlowDTO is ===="+mcfeReversalFlowDTO);
			mcfeReversalFlowDao.insertReversalFlow(mcfeReversalFlowDTO);
			amount = amountMap.get("amount");
			
			//当还款计划状态变为正常或结清时修改催收表状态
			if((plan.getStatus()==MarvelsConstant.CONTRACT_ACCOUNT_STATUS_NORMAL ||plan.getStatus()==MarvelsConstant.PAYMENT_PLAN_STATUS_COMPLETE)
					&& StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())) {
				try {
					overdueCollectTaskDao.urgentByLoanId(plan.getLoanId());
				}catch(Exception ex) {
					MarvelsLogUtil.getInstance().error("更新催收记录为出催失败,loanId="+plan.getLoanId(),ex);
				}
				
			}
			//System.out.println("the amount = "+amount);
		}		
	}
	
	
	/**更新还款计划
	 * @author 娄凯琦
	 * @date 2018年5月23日  
	 * @param amount
	 * @param sequenceList
	 * @param plan
	 * @param mcfeRepaymentFlowDTO
	 */
	
	private Map<String,BigDecimal> updateLoanPlan(BigDecimal amount,List<McptPaymentSequenceItemDTO> sequenceList,McfeCustomerRepaymentPlanDTO plan,McfeRepaymentFlowDTO mcfeRepaymentFlowDTO,Date date,List<McfeReversalDetailDTO> reversalList) throws MarvelsBusinessException{
		MarvelsLogUtil.getInstance().info("call LoanAfterInfoApiImpl updateLoanPlan staring "+"[sequenceList="+JSON.toJSONString(sequenceList)+"] [plan="+JSON.toJSONString(plan)+"] [mcfeRepaymentFlowDTO="+JSON.toJSONString(mcfeRepaymentFlowDTO)+"] [reversalList="+JSON.toJSONString(reversalList)+"]");
		
		BigDecimal custRepaymentAmount = new BigDecimal(amount.doubleValue());
		
		String groupName = mcfeRepaymentFlowDTO.getGroupEng();//获取冲账组合
        String[] group = null;
        if(groupName!=null&&!"".equals(groupName.trim())){
        	group = groupName.split(";");
        }
        if(sequenceList==null || sequenceList.size()<1){
        	throw new MarvelsBusinessException("未匹配到冲账顺序配置");
        }
        Map<String,BigDecimal> moneyMap = new HashMap<String,BigDecimal>();//冲账金额明细
        //更新还款计划表
		String updateBy="";
		String createBy="";
    	UserDTO userDTO=null;
    	try{
    		userDTO=CacheUtils.getCacheUser();
    	}catch(Exception e){
    		MarvelsLogUtil.getInstance().error(">>>>>>>>获取当前信息异常:",e);
    	}
    	if(userDTO==null){
    		updateBy="system";
    		createBy="system";
    	}else{
    		updateBy=userDTO.getUserCode();
    		createBy=userDTO.getUserCode();
    	}
    	
    	BigDecimal currentPaymenPrincipal = plan.getCurrentPaymentPrincipal();
    	BigDecimal currentPaymentManagement = plan.getCurrentPaymentManagementFee();
    	//客户所有剩余应还款金额
    	BigDecimal allNeedRepaymentAmount = plan.getPrincipal().subtract(plan.getPrincipalAct()).add(plan.getInterest()).subtract(plan.getInterestAct())
        		.add(plan.getManagementFee()).subtract(plan.getManagementFeeAct()).add(plan.getPenaltyFee()).subtract(plan.getPenaltyFeeAct())
        		.add(plan.getLateFee()).subtract(plan.getLateFeeAct()).add(plan.getPlatformFee()).subtract(plan.getPlatformFeeAct())
        		.add(plan.getMiscFee()).subtract(plan.getMiscFeeAct()).subtract(plan.getPrincipalWaive()).subtract(plan.getInterestWaive())
        		.subtract(plan.getConsultingFeeWaive()).subtract(plan.getManagementFeeWaive()).subtract(plan.getPenaltyFeeWaive()).subtract(plan.getLateFeeWaive())
        		.subtract(plan.getPreTerminateFeeWaive());
    	
        for(McptPaymentSequenceItemDTO sequenceDto:sequenceList){
        	String fieldCode = sequenceDto.getFieldCode();
        	
        	if(group!=null){
	        	boolean judge = false;
	        	for(int i = 0;i<group.length;i++){
		        if(fieldCode.equals(group[i])){
		        		judge = true;
		        		break;
		        	};
	        	}
	        	if(!judge){
	        		continue;
	        	}
        	}
        	//根据冲账循序进行冲账
        	BigDecimal payMoney = BigDecimal.ZERO.setScale(2);//未还金额
        	BigDecimal trueMoney = BigDecimal.ZERO.setScale(2);//实还金额
        	McfeReversalDetailDTO reversalDto = new McfeReversalDetailDTO();
        	if("principal".equals(fieldCode)){
        		reversalDto.setTransactionName("本金");
        		reversalDto.setTransactionCode("principal");
        		
        		// 依据配置决定冲本金金额
        		// 当配置为Y时，放款T+1日开始扣款，在无展期情况下每日扣款金额为150元，扣7天。任意一日未扣取到则将其金额进行累加到下一扣款日中
        		//           如果做了展期则扣款日减一天
        		if(StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())) {
        			payMoney = plan.getPrincipal().subtract(plan.getPrincipalAct()).subtract(plan.getPrincipalWaive());
        			//如果还款金额大于当期应还本金则冲销对应当期应还本金,否则还款金额有多少则冲销多少本金
        			if(custRepaymentAmount.compareTo(allNeedRepaymentAmount) >= 0){
        				amount = amount.subtract(payMoney);
            			plan.setPrincipalAct(plan.getPrincipalAct().add(payMoney));
            			moneyMap.put("principal", payMoney);
            			trueMoney = payMoney;
        			}else if(amount.compareTo(currentPaymenPrincipal)>=0 && !StringUtils.equals("2", mcfeRepaymentFlowDTO.getPayType())) {
        				plan.setPrincipalAct(plan.getPrincipalAct().add(currentPaymenPrincipal));
        				moneyMap.put("principal", currentPaymenPrincipal);
        				amount = amount.subtract(currentPaymenPrincipal);
        				trueMoney = currentPaymenPrincipal;
        			}else {
        				plan.setPrincipalAct(plan.getPrincipalAct().add(amount));
            			moneyMap.put("principal", amount);
            			trueMoney = amount;
            			amount = BigDecimal.ZERO; 
        			}
        		}else {
        			payMoney = plan.getPrincipal().subtract(plan.getPrincipalAct()).subtract(plan.getPrincipalWaive());
            		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
            			amount = amount.subtract(payMoney);
            			plan.setPrincipalAct(plan.getPrincipalAct().add(payMoney));
            			moneyMap.put("principal", payMoney);
            			trueMoney = payMoney;
            		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
            			plan.setPrincipalAct(plan.getPrincipalAct().add(amount));
            			moneyMap.put("principal", amount);
            			trueMoney = amount;
            			amount = BigDecimal.ZERO;  			
            		}        			
        		}
        	}else if("interest".equals(fieldCode)){
        		reversalDto.setTransactionName("利息");
        		reversalDto.setTransactionCode("interest");
        		payMoney = plan.getInterest().subtract(plan.getInterestAct()).subtract(plan.getInterestWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setInterestAct(plan.getInterestAct().add(payMoney));
        			moneyMap.put("interest", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setInterestAct(plan.getInterestAct().add(amount));
        			moneyMap.put("interest", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("consultingFee".equals(fieldCode)){
        		reversalDto.setTransactionName("咨询费");
        		reversalDto.setTransactionCode("consultingFee");
        		payMoney = plan.getConsultingFee().subtract(plan.getConsultingFeeAct()).subtract(plan.getConsultingFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setConsultingFeeAct(plan.getConsultingFeeAct().add(payMoney));
        			moneyMap.put("consultingFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setConsultingFeeAct(plan.getConsultingFeeAct().add(amount));
        			moneyMap.put("consultingFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        		
        	}else if("managementFee".equals(fieldCode)){
        		reversalDto.setTransactionName("管理费");
        		reversalDto.setTransactionCode("managementFee");
        		
        		// 依据配置决定冲本金金额
        		// 当配置为Y时，放款T+1日开始扣款，在无展期情况下每日扣款金额为150元，扣7天。任意一日未扣取到则将其金额进行累加到下一扣款日中
        		//           如果做了展期则扣款日减一天
        		if(StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())) {
        			payMoney = plan.getManagementFee().subtract(plan.getManagementFeeAct()).subtract(plan.getManagementFeeWaive());
        			//如果还款金额大于当前应还管理费则冲销对应前应还管理费,否则还款金额有多少则冲销多少管理费
        			if(custRepaymentAmount.compareTo(allNeedRepaymentAmount) >= 0){
        				amount = amount.subtract(payMoney);
            			plan.setManagementFeeAct(plan.getManagementFeeAct().add(payMoney));
            			moneyMap.put("managementFee", payMoney);
            			trueMoney = payMoney;
        			}else if(amount.compareTo(currentPaymentManagement)>=0  && !StringUtils.equals("2", mcfeRepaymentFlowDTO.getPayType())) {
        				plan.setManagementFeeAct(plan.getManagementFeeAct().add(currentPaymentManagement));
        				moneyMap.put("managementFee", currentPaymentManagement);
        				amount = amount.subtract(currentPaymentManagement);
        				trueMoney = currentPaymentManagement;
        			}else {
        				plan.setManagementFeeAct(plan.getManagementFeeAct().add(amount));
            			moneyMap.put("managementFee", amount);
            			trueMoney = amount;
            			amount = BigDecimal.ZERO; 
        			}
        		}else {
        			payMoney = plan.getManagementFee().subtract(plan.getManagementFeeAct()).subtract(plan.getManagementFeeWaive());
            		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
            			amount = amount.subtract(payMoney);
            			plan.setManagementFeeAct(plan.getManagementFeeAct().add(payMoney));
            			moneyMap.put("managementFee", payMoney);
            			trueMoney = payMoney;
            		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
            			plan.setManagementFeeAct(plan.getManagementFeeAct().add(amount));
            			moneyMap.put("managementFee", amount);
            			trueMoney = amount;
            			amount = BigDecimal.ZERO;
            		}        			
        		}
        	}else if("penaltyFee".equals(fieldCode)){
        		reversalDto.setTransactionName("违约金");
        		reversalDto.setTransactionCode("penaltyFee");
        		payMoney = plan.getPenaltyFee().subtract(plan.getPenaltyFeeAct()).subtract(plan.getPenaltyFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setPenaltyFeeAct(plan.getPenaltyFeeAct().add(payMoney));
        			moneyMap.put("penaltyFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setPenaltyFeeAct(plan.getPenaltyFeeAct().add(amount));
        			moneyMap.put("penaltyFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("lateFee".equals(fieldCode)){
        		reversalDto.setTransactionName("滞纳金");
        		reversalDto.setTransactionCode("lateFee");
        		payMoney = plan.getLateFee().subtract(plan.getLateFeeAct()).subtract(plan.getLateFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setLateFeeAct(plan.getLateFeeAct().add(payMoney));
        			moneyMap.put("lateFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setLateFeeAct(plan.getLateFeeAct().add(amount));
        			moneyMap.put("lateFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("preTerminateFee".equals(fieldCode)){
        		reversalDto.setTransactionName("提前结清费");
        		reversalDto.setTransactionCode("preTerminateFee");
        		payMoney = plan.getPreTerminateFee().subtract(plan.getPreTerminateFeeAct()).subtract(plan.getPreTerminateFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setPreTerminateFeeAct(plan.getPreTerminateFeeAct().add(payMoney));
        			moneyMap.put("preTerminateFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setPreTerminateFeeAct(plan.getPreTerminateFeeAct().add(amount));
        			moneyMap.put("preTerminateFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("miscFee".equals(fieldCode)){
        		reversalDto.setTransactionName("杂费");
        		reversalDto.setTransactionCode("miscFee");
        		payMoney = plan.getMiscFee().subtract(plan.getMiscFeeAct()).subtract(plan.getMiscFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setMiscFeeAct(plan.getMiscFeeAct().add(payMoney));
        			moneyMap.put("miscFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setMiscFeeAct(plan.getMiscFeeAct().add(amount));
        			moneyMap.put("miscFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("platformFee".equals(fieldCode)){
        		reversalDto.setTransactionName("平台费");
        		reversalDto.setTransactionCode("platformFee");
        		payMoney = plan.getPlatformFee().subtract(plan.getPlatformFeeAct()).subtract(plan.getPlatformFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setPlatformFeeAct(plan.getPlatformFeeAct().add(payMoney));
        			moneyMap.put("platformFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setPlatformFeeAct(plan.getPlatformFeeAct().add(amount));
        			moneyMap.put("platformFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}
        	
        	if(trueMoney.compareTo(BigDecimal.ZERO) > 0){
        		reversalDto.setCustCardNo(mcfeRepaymentFlowDTO.getCustCardNo());
        		reversalDto.setCustName(mcfeRepaymentFlowDTO.getCustName());
        		reversalDto.setMobile(mcfeRepaymentFlowDTO.getMobile());
        		reversalDto.setLoanId(mcfeRepaymentFlowDTO.getLoanId());
        		reversalDto.setCreatedBy(createBy);
        		reversalDto.setUpdatedBy(updateBy);
        		reversalDto.setTransctionSeq(mcfeRepaymentFlowDTO.getTransctionSeq());
        		reversalDto.setAmount(trueMoney);
        		reversalDto.setReversalAmount(trueMoney);
        		reversalDto.setRemark("");
        		reversalDto.setTransationDate(date);
        		reversalDto.setReversalDate(date);
        		reversalDto.setPlanCode(plan.getPlanCode());
        		reversalList.add(reversalDto);
        	}
    		
        	if(amount.compareTo(BigDecimal.ZERO) < 1){
        		break;
        	}
        }
         
        BigDecimal needAmount = plan.getPrincipal().subtract(plan.getPrincipalAct()).add(plan.getInterest()).subtract(plan.getInterestAct())
        		.add(plan.getManagementFee()).subtract(plan.getManagementFeeAct()).add(plan.getPenaltyFee()).subtract(plan.getPenaltyFeeAct())
        		.add(plan.getLateFee()).subtract(plan.getLateFeeAct()).add(plan.getPlatformFee()).subtract(plan.getPlatformFeeAct())
        		.add(plan.getMiscFee()).subtract(plan.getMiscFeeAct()).subtract(plan.getPrincipalWaive()).subtract(plan.getInterestWaive())
        		.subtract(plan.getConsultingFeeWaive()).subtract(plan.getManagementFeeWaive()).subtract(plan.getPenaltyFeeWaive()).subtract(plan.getLateFeeWaive())
        		.subtract(plan.getPreTerminateFeeWaive());
        
        //定义当前应还款金额
        BigDecimal currentPaymentAmount = BigDecimal.ZERO;
        if(StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())) {
        	currentPaymentAmount = currentPaymenPrincipal.add(currentPaymentManagement).add(plan.getInterest()).subtract(plan.getInterestAct())
        			.add(plan.getPenaltyFee()).subtract(plan.getPenaltyFeeAct()).add(plan.getLateFee()).subtract(plan.getLateFeeAct()).add(plan.getPlatformFee())
        			.subtract(plan.getPlatformFeeAct()).add(plan.getMiscFee()).subtract(plan.getMiscFeeAct()).subtract(plan.getInterestWaive())
        			.subtract(plan.getPenaltyFeeWaive()).subtract(plan.getLateFeeWaive()).subtract(plan.getPreTerminateFeeWaive());
        }
        if(needAmount.compareTo(BigDecimal.ZERO) < 1){
        	plan.setStatus(MarvelsConstant.PAYMENT_PLAN_STATUS_COMPLETE);//如果该笔还款计划金额应还与实还金额差值为零则修改状态为完成
        	plan.setPaymentDateAct(date);
        }else if(plan.getStatus() == MarvelsConstant.CONTRACT_ACCOUNT_STATUS_DELQ && custRepaymentAmount.compareTo(currentPaymentAmount)>=0) {
        	plan.setStatus(MarvelsConstant.PAYMENT_PLAN_STATUS_NORMAL);
        	plan.setDelqDays(0);
        }
        plan.setUpdatedBy(MarvelsConstant.SYSTEM_USER);
        plan.setUpdatedDate(date);
        moneyMap.put("amount", amount);
        return moneyMap;
	}
	
	
	/**更新合同金额
	 * @author 娄凯琦
	 * @date 2018年5月24日  
	 * @param contract
	 * @param plan
	 * @param date
	 * @param map
	 */
	private void updateContractInfo(McfeCustomerLoanContractDTO contract,McfeCustomerRepaymentPlanDTO plan,Date date,Map<String,BigDecimal> map,BigDecimal needAmount){
		Set<String> set = map.keySet();
		for(String fieldCode:set){
			if("principal".equals(fieldCode)){
				contract.setPrincipal(contract.getPrincipal().add(map.get(fieldCode)));
				contract.setPrincipalOs(contract.getPrincipalOs().subtract(map.get(fieldCode)));
        	}else if("interest".equals(fieldCode)){
        		contract.setInterest(contract.getInterest().add(map.get(fieldCode)));
        		contract.setInterestOs(contract.getInterestOs().subtract(map.get(fieldCode)));
        	}else if("consultingFee".equals(fieldCode)){
        		contract.setConsultingFee(contract.getConsultingFee().add(map.get(fieldCode)));
        		contract.setConsultingFeeOs(contract.getConsultingFeeOs().subtract(map.get(fieldCode)));
        	}else if("managementFee".equals(fieldCode)){
        		contract.setManagementFee(contract.getManagementFee().add(map.get(fieldCode)));
        		contract.setManagementFeeOs(contract.getManagementFeeOs().subtract(map.get(fieldCode)));
        	}else if("penaltyFee".equals(fieldCode)){
        		contract.setPenaltyFee(contract.getPenaltyFee().add(map.get(fieldCode)));
        		contract.setPenaltyFeeOs(contract.getPenaltyFeeOs().subtract(map.get(fieldCode)));
        	}else if("lateFee".equals(fieldCode)){
        		contract.setLateFee(contract.getLateFee().add(map.get(fieldCode)));
        		contract.setLateFeeOs(contract.getLateFeeOs().subtract(map.get(fieldCode)));
        	}else if("preTerminateFee".equals(fieldCode)){
        		contract.setPreTerminateFee(contract.getPreTerminateFee().add(map.get(fieldCode)));
        		contract.setPreTerminateFeeOs(contract.getPreTerminateFeeOs().subtract(map.get(fieldCode)));
        	}else if("miscFee".equals(fieldCode)){
        		contract.setMiscFee(contract.getMiscFee().add(map.get(fieldCode)));
        		contract.setMiscFeeOs(contract.getMiscFeeOs().subtract(map.get(fieldCode)));
        	}else if("platformFee".equals(fieldCode)){
        		contract.setPlatformFee(contract.getPlatformFee().add(map.get(fieldCode)));
        		contract.setPlatformFeeOs(contract.getPlatformFeeOs().subtract(map.get(fieldCode)));
        	}
		}
        if(needAmount.compareTo(BigDecimal.ZERO) < 1){
	        List<McfeCustomerRepaymentPlanDTO> list = mcfeCustomerRepaymentPlanDao.selectAllUncompletedPlan(plan.getLoanId());
	        Integer delqDays = 0;
	        for (McfeCustomerRepaymentPlanDTO mppi :list){
	            if (MarvelsConstant.CONTRACT_ACCOUNT_STATUS_DELQ.equals(mppi.getStatus()) && mppi.getDelqDays()>delqDays){	// && !(mppi.getId().equals(planInfo.getId()))
	                delqDays=mppi.getDelqDays();
	            }
	        }
        	//判断是否是最后一期，是则更新借款合同为"A2"（"还款完成"）
            if(plan.getTenor().intValue() == contract.getTenor().intValue()) {
            	contract.setStatus(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_COMPLETE);
            	contract.setDelqDays(0);
            	contract.setForceFlag(MarvelsConstant.FORCE_COLLECTION_FLAG_A0);
            }else if(delqDays.intValue() > 0) {
            	contract.setStatus(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_DELQ);
            	contract.setDelqDays(delqDays);
            } else {
            	contract.setStatus(MarvelsConstant.CONTRACT_ACCOUNT_STATUS_NORMAL);
            	contract.setDelqDays(0);
            	contract.setForceFlag(MarvelsConstant.FORCE_COLLECTION_FLAG_A0);
            }
            contract.setCurrTenor(plan.getTenor());
        }else if(StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())){
			//当配置为分期时，单独计算应还款日 
        	contract.setStatus(plan.getStatus());
        	contract.setDelqDays(plan.getDelqDays());
        }
        contract.setUpdatedBy(MarvelsConstant.SYSTEM_USER);
        contract.setUpdatedDate(date);
	}
	
	/**更新客户贷款信息表
	 * @author 娄凯琦
	 * @date 2018年5月24日  
	 * @param CustomerLoanInfoDTO
	 * @param plan
	 * @param date
	 * @param map
	 * @param needAmount
	 */
	private void updateCustomerLoanInfo(McfeCustomerLoanInfoDTO customerLoanInfoDTO,McfeCustomerRepaymentPlanDTO plan,Date date,Map<String,BigDecimal> map,BigDecimal needAmount,McfeCustomerLoanContractDTO contract){
		Set<String> set = map.keySet();
		for(String fieldCode:set){
			if("principal".equals(fieldCode)){
				customerLoanInfoDTO.setPrincipal(customerLoanInfoDTO.getPrincipal().add(map.get(fieldCode)));
				customerLoanInfoDTO.setPrincipalOs(customerLoanInfoDTO.getPrincipalOs().subtract(map.get(fieldCode)));
        	}else if("interest".equals(fieldCode)){
        		customerLoanInfoDTO.setInterest(customerLoanInfoDTO.getInterest().add(map.get(fieldCode)));
        		customerLoanInfoDTO.setInterestOs(customerLoanInfoDTO.getInterestOs().subtract(map.get(fieldCode)));
        	}else if("consultingFee".equals(fieldCode)){
        		customerLoanInfoDTO.setConsultingFee(customerLoanInfoDTO.getConsultingFee().add(map.get(fieldCode)));
        		customerLoanInfoDTO.setConsultingFeeOs(customerLoanInfoDTO.getConsultingFeeOs().subtract(map.get(fieldCode)));
        	}else if("managementFee".equals(fieldCode)){
        		customerLoanInfoDTO.setManagementFee(customerLoanInfoDTO.getManagementFee().add(map.get(fieldCode)));
        		customerLoanInfoDTO.setManagementFeeOs(customerLoanInfoDTO.getManagementFeeOs().subtract(map.get(fieldCode)));
        	}else if("penaltyFee".equals(fieldCode)){
        		customerLoanInfoDTO.setPenaltyFee(customerLoanInfoDTO.getPenaltyFee().add(map.get(fieldCode)));
        		customerLoanInfoDTO.setPenaltyFeeOs(customerLoanInfoDTO.getPenaltyFeeOs().subtract(map.get(fieldCode)));
        	}else if("lateFee".equals(fieldCode)){
        		customerLoanInfoDTO.setLateFee(customerLoanInfoDTO.getLateFee().add(map.get(fieldCode)));
        		customerLoanInfoDTO.setLateFeeOs(customerLoanInfoDTO.getLateFeeOs().subtract(map.get(fieldCode)));
        	}else if("preTerminateFee".equals(fieldCode)){
        		customerLoanInfoDTO.setPreTerminateFee(customerLoanInfoDTO.getPreTerminateFee().add(map.get(fieldCode)));
        		customerLoanInfoDTO.setPreTerminateFeeOs(customerLoanInfoDTO.getPreTerminateFeeOs().subtract(map.get(fieldCode)));
        	}else if("miscFee".equals(fieldCode)){
        		customerLoanInfoDTO.setMiscFee(customerLoanInfoDTO.getMiscFee().add(map.get(fieldCode)));
        		customerLoanInfoDTO.setMiscFeeOs(customerLoanInfoDTO.getMiscFeeOs().subtract(map.get(fieldCode)));
        	}else if("platformFee".equals(fieldCode)){
        		customerLoanInfoDTO.setPlatformFee(customerLoanInfoDTO.getPlatformFee().add(map.get(fieldCode)));
        		customerLoanInfoDTO.setPlatformFeeOs(customerLoanInfoDTO.getPlatformFeeOs().subtract(map.get(fieldCode)));
        	}
		}
		customerLoanInfoDTO.setStatus(contract.getStatus());
		customerLoanInfoDTO.setUpdatedBy(MarvelsConstant.SYSTEM_USER);
		customerLoanInfoDTO.setUpdatedDate(date);
	}

	@Override
	public McfeCustomerLoanContractDTO selectContractByLoanId(String loanId) {
		return mcfeCustomerLoanContractDao.selectContractByLoanId(loanId);
	}

	@Override
	public Map<String, Object> overdueCustList(OverDueCustApiDTO overDueCustApiDto) throws MarvelsBusinessException {
		if(overDueCustApiDto==null) throw new MarvelsBusinessException("入参为空");
		List<String> userIdList = this.getUserIdList(overDueCustApiDto);
		Integer pageNo = overDueCustApiDto.getPageNo();
		Integer pageSize = overDueCustApiDto.getPageSize();
		String custName = overDueCustApiDto.getCustName();
		String sortType = overDueCustApiDto.getSortType();
		String sortRule = overDueCustApiDto.getSortRule();
		if(CollectionUtils.isEmpty(userIdList)){
			return null;
		}
		if(null == pageNo || pageNo < 1){
			pageNo = 1;
		}
		if(null == pageSize || pageSize < 1){
			pageSize = 20;
		}
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("userList", userIdList);
		map.put("custName", custName);
		
		//防止出现NPE
		if(StringUtils.isNotBlank(sortRule) && StringUtils.isNotBlank(sortType)){
			if("1".equals(sortType)){
				map.put("delqDays", "delqDays");
			}else if("2".equals(sortType)){
				map.put("senondChannel", "senondChannel");
			}else if("3".equals(sortType)){
				map.put("delqAmount", "delqAmount");
			}
			map.put("sortRule", "1".equals(sortRule)?"asc":"desc");
		}
		PageHelper.startPage(pageNo, pageSize);
		List<Map<String,Object>> resultList = mcfeCustomerRepaymentPlanDao.selectOverdueCust(map);
		PageInfo<Map<String,Object>> page = new PageInfo<Map<String,Object>>(resultList);
		return PageConverter.converter(page);
	}

	private List<String> getUserIdList(OverDueCustApiDTO overDueCustApiDto) {
		List<String> resultList = new ArrayList<String>();
		List<CmsEmployeeInfoDTO> cmsEmployees = consumerUmApi.findUserIdByEmp(overDueCustApiDto.getUserId(),overDueCustApiDto.getUserType());
		if(!CollectionUtils.isEmpty(cmsEmployees)){
			for (CmsEmployeeInfoDTO entity : cmsEmployees) {
				if(null!=entity.getUserId()){
					resultList.add(entity.getUserId().toString());
				}
			}
		}
		return resultList;
	}

	@Override
	public void customerLoanInfoCommon(McfeCustomerLoanInfoDTO customerLoanInfo) throws MarvelsBusinessException{
		if(customerLoanInfo==null){
			throw new MarvelsBusinessException("客户贷款信息传入不能为空");
		}
		String idNumber=customerLoanInfo.getCustCardNo();
		if(StringUtils.isEmpty(idNumber)){
			throw new MarvelsBusinessException("身份证不能为空");
		}
		//先查询该身份证是否存在客户贷款信息
		McfeCustomerLoanInfoDTO dto=mcfeCustomerLoanInfoDao.selectCustomerLoanInfoByIdNumber(idNumber);
		if(dto==null){//不存在则插入
			mcfeCustomerLoanInfoDao.insertCustomerLoanInfo(customerLoanInfo);
		}else{//
			dto.setLoanId(customerLoanInfo.getLoanId());
			dto.setStatus(0);// 0正常 1逾期 2结清
			dto.setPrincipalOs(customerLoanInfo.getPrincipalOs());
			dto.setInterestOs(customerLoanInfo.getInterestOs());
			dto.setConsultingFeeOs(customerLoanInfo.getConsultingFeeOs());
			dto.setManagementFeeOs(customerLoanInfo.getManagementFeeOs());
			dto.setPenaltyFeeOs(customerLoanInfo.getPenaltyFeeOs());
			dto.setLateFeeOs(customerLoanInfo.getLateFeeOs());
			dto.setPreTerminateFeeOs(customerLoanInfo.getPreTerminateFeeOs());
			dto.setMiscFeeOs(customerLoanInfo.getMiscFeeOs());
			dto.setPlatformFeeOs(customerLoanInfo.getPlatformFeeOs());
			UserDTO userDTO=null;
			try {
				userDTO=CacheUtils.getCacheUser();
			} catch (Exception e) {
				
			}
			dto.setUpdatedBy(userDTO==null?"system":userDTO.getUserCode());
			dto.setUpdatedDate(new Date());
			mcfeCustomerLoanInfoDao.updateCustomerLoanInfoById(dto);
		}
		
	}
	
	@Override
	public List<String> overdueLoanList(ApprovalProcessConditionDTO dto){
		Integer pageNo = dto.getPageNum();
		Integer pageSize = dto.getPageSize();
		if(null == pageNo || pageNo < 1){
			pageNo = 1;
		}
		if(null == pageSize || pageSize < 1){
			pageSize = 10;
		}
		PageHelper.startPage(pageNo, pageSize);
		return mcfeCustomerLoanContractDao.overdueLoanList(dto);
	}
	
	/**模拟冲账逻辑
	 * @author:wujunfeng
	 */
	public static void main(String[] args) {
		String sequenceListStr = "[{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"principal\",\"fieldName\":\"本金\",\"id\":11,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":1,\"updatedBy\":\"system\",\"updatedDate\":1545400938000},{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"interest\",\"fieldName\":\"利息\",\"id\":12,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":2,\"updatedBy\":\"system\",\"updatedDate\":1545400938000},{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"consultingFee\",\"fieldName\":\"服务费（成本）\",\"id\":13,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":3,\"updatedBy\":\"system\",\"updatedDate\":1545400938000},{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"managementFee\",\"fieldName\":\"服务费（手续费）\",\"id\":14,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":4,\"updatedBy\":\"system\",\"updatedDate\":1545400938000},{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"penaltyFee\",\"fieldName\":\"罚费（违约金）\",\"id\":15,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":5,\"updatedBy\":\"system\",\"updatedDate\":1545400938000},{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"lateFee\",\"fieldName\":\"罚费（滞纳金）\",\"id\":16,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":6,\"updatedBy\":\"system\",\"updatedDate\":1545400938000},{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"miscFee\",\"fieldName\":\"杂费\",\"id\":17,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":7,\"updatedBy\":\"system\",\"updatedDate\":1545400938000},{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"A7\",\"fieldName\":\"风险金\",\"id\":18,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":8,\"updatedBy\":\"system\",\"updatedDate\":1545400938000},{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"platformFee\",\"fieldName\":\"平台费\",\"id\":19,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":9,\"updatedBy\":\"system\",\"updatedDate\":1545400938000},{\"createdBy\":\"system\",\"createdDate\":1545400938000,\"deleteFlag\":0,\"fieldCode\":\"preTerminateFee\",\"fieldName\":\"提前结清费\",\"id\":20,\"paymentSequenceCode\":\"HK2cdc62db9c574092aac71c9f0f1fdcf4\",\"sort\":10,\"updatedBy\":\"system\",\"updatedDate\":1545400938000}]";
		String planStr = "{\"alreadyAmount\":0.00,\"amount\":0.00,\"channelCode\":\"wxo2\",\"channelName\":\"ZXJ3\",\"consultingFee\":570.00,\"consultingFeeAct\":570.00,\"consultingFeeWaive\":0.00,\"createdBy\":\"system\",\"createdDate\":1563252450000,\"currentPaymentManagementFee\":0.00,\"currentPaymentPrincipal\":1697.00,\"custCardNo\":\"420105197710091611\",\"custName\":\"魏翔\",\"deleteFlag\":0,\"delqDays\":0,\"fundCode\":\"1\",\"fundConsultingFee\":0.00,\"fundConsultingFeeAct\":0.00,\"fundConsultingFeeWaive\":0.00,\"fundInterest\":0.00,\"fundInterestAct\":0.00,\"fundInterestWaive\":0.00,\"fundLateFee\":0.00,\"fundLateFeeAct\":0.00,\"fundLateFeeWaive\":0.00,\"fundManagementFee\":0.00,\"fundManagementFeeAct\":0.00,\"fundManagementFeeWaive\":0.00,\"fundMiscFee\":0.00,\"fundMiscFeeAct\":0.00,\"fundMiscFeeWaive\":0.00,\"fundName\":\"微粒速贷\",\"fundPenaltyFee\":0.00,\"fundPenaltyFeeAct\":0.00,\"fundPenaltyFeeWaive\":0.00,\"fundPlatformFee\":0.00,\"fundPlatformFeeAct\":0.00,\"fundPlatformFeeWaive\":0.00,\"fundPreTerminateFee\":0.00,\"fundPreTerminateFeeAct\":0.00,\"fundPreTerminateFeeWaive\":0.00,\"fundPrincipal\":1900.00,\"fundPrincipalAct\":0.00,\"fundPrincipalWaive\":0.00,\"fundRiskFee\":0.00,\"fundRiskFeeAct\":0.00,\"fundRiskFeeWaive\":0.00,\"id\":\"6227\",\"interest\":0.00,\"interestAct\":0.00,\"interestWaive\":0.00,\"lateFee\":0.00,\"lateFeeAct\":0.00,\"lateFeeWaive\":0.00,\"loanId\":\"1719071611111646437\",\"managementFee\":0.00,\"managementFeeAct\":0.00,\"managementFeeWaive\":0.00,\"miscFee\":0.00,\"miscFeeAct\":0.00,\"miscFeeWaive\":0.00,\"paymentDate\":1563724800000,\"paymentDateLate\":1563811200000,\"penaltyFee\":0.00,\"penaltyFee1\":0.00,\"penaltyFee2\":0.00,\"penaltyFeeAct\":0.00,\"penaltyFeeWaive\":0.00,\"planCode\":\"FE44bd4346c24d4de4bde4233821307b2f\",\"platformFee\":0.00,\"platformFeeAct\":0.00,\"platformFeeWaive\":0.00,\"preTerminateFee\":0.00,\"preTerminateFeeAct\":0.00,\"preTerminateFeeWaive\":0.00,\"principal\":1900.00,\"principalAct\":0.00,\"principalWaive\":200.00,\"productCode\":\"PTcccce904a7cc468d94b87821c6006c54\",\"productName\":\"守信金贷-103-1-A\",\"productType\":\"10\",\"productTypeName\":\"守信金贷\",\"repayAmount\":0.00,\"riskFee\":0.00,\"riskFeeAct\":0.00,\"riskFeeWaive\":0.00,\"serviceFee2\":0.00,\"shouldAmount\":0.00,\"status\":0,\"tenor\":1,\"updatedBy\":\"飞\",\"updatedDate\":1563872703000}";
		String mcfeRepaymentFlowDTOStr = "{\"amount\":0,\"amountAct\":1700.00,\"bankCardNo\":\"6217002870074365352\",\"bankHeadLink\":\"\",\"bankName\":\"魏翔\",\"batName\":\"b94b794a950040b29bc8cb7a330a5e76\",\"channelCode\":\"wxo2\",\"channelName\":\"ZXJ3\",\"createdBy\":\"飞\",\"createdDate\":1563872738000,\"custCardNo\":\"420105197710091611\",\"custName\":\"魏翔\",\"deleteFlag\":0,\"fundCode\":\"1\",\"fundName\":\"微粒速贷\",\"id\":4835,\"loanId\":\"1719071611111646437\",\"mobile\":\"13007168046\",\"payType\":\"1\",\"productCode\":\"PTcccce904a7cc468d94b87821c6006c54\",\"productName\":\"守信金贷\",\"productType\":\"10\",\"productTypeName\":\"守信金贷\",\"repayStyle\":\"3\",\"reqChannel\":\"006\",\"status\":\"1\",\"tranctionDate\":1563872738000,\"transctionSeq\":\"DH156387273296541235161\",\"updatedBy\":\"system\",\"updatedDate\":1563872760000}";
		BigDecimal amount = new BigDecimal(1700);
		List<McptPaymentSequenceItemDTO> sequenceList = JSONUtil.toList(JSONUtil.parseArray(sequenceListStr), McptPaymentSequenceItemDTO.class);
		McfeCustomerRepaymentPlanDTO plan = JSONUtil.toBean(planStr, McfeCustomerRepaymentPlanDTO.class);
		McfeRepaymentFlowDTO mcfeRepaymentFlowDTO = JSONUtil.toBean(mcfeRepaymentFlowDTOStr, McfeRepaymentFlowDTO.class);
		Date date = DateUtil.parse("2019-07-23");
		List<McfeReversalDetailDTO> reversalList = new ArrayList<McfeReversalDetailDTO>();
		
		
		MarvelsLogUtil.getInstance().info("call LoanAfterInfoApiImpl updateLoanPlan staring "+"[sequenceList="+JSON.toJSONString(sequenceList)+"] [plan="+JSON.toJSONString(plan)+"] [mcfeRepaymentFlowDTO="+JSON.toJSONString(mcfeRepaymentFlowDTO)+"] [reversalList="+JSON.toJSONString(reversalList)+"]");
		
		BigDecimal custRepaymentAmount = new BigDecimal(amount.doubleValue());
		
		String groupName = mcfeRepaymentFlowDTO.getGroupEng();//获取冲账组合
        String[] group = null;
        if(groupName!=null&&!"".equals(groupName.trim())){
        	group = groupName.split(";");
        }
        if(sequenceList==null || sequenceList.size()<1){
        	// throw new MarvelsBusinessException("未匹配到冲账顺序配置");
        }
        Map<String,BigDecimal> moneyMap = new HashMap<String,BigDecimal>();//冲账金额明细
        //更新还款计划表
		String updateBy="";
		String createBy="";
    	UserDTO userDTO=null;
    	try{
    		userDTO=CacheUtils.getCacheUser();
    	}catch(Exception e){
    		MarvelsLogUtil.getInstance().error(">>>>>>>>获取当前信息异常:",e);
    	}
    	if(userDTO==null){
    		updateBy="system";
    		createBy="system";
    	}else{
    		updateBy=userDTO.getUserCode();
    		createBy=userDTO.getUserCode();
    	}
    	
    	BigDecimal currentPaymenPrincipal = plan.getCurrentPaymentPrincipal();
    	BigDecimal currentPaymentManagement = plan.getCurrentPaymentManagementFee();
    	//客户所有剩余应还款金额
    	BigDecimal allNeedRepaymentAmount = plan.getPrincipal().subtract(plan.getPrincipalAct()).add(plan.getInterest()).subtract(plan.getInterestAct())
        		.add(plan.getManagementFee()).subtract(plan.getManagementFeeAct()).add(plan.getPenaltyFee()).subtract(plan.getPenaltyFeeAct())
        		.add(plan.getLateFee()).subtract(plan.getLateFeeAct()).add(plan.getPlatformFee()).subtract(plan.getPlatformFeeAct())
        		.add(plan.getMiscFee()).subtract(plan.getMiscFeeAct()).subtract(plan.getPrincipalWaive()).subtract(plan.getInterestWaive())
        		.subtract(plan.getConsultingFeeWaive()).subtract(plan.getManagementFeeWaive()).subtract(plan.getPenaltyFeeWaive()).subtract(plan.getLateFeeWaive())
        		.subtract(plan.getPreTerminateFeeWaive());
    	
        for(McptPaymentSequenceItemDTO sequenceDto:sequenceList){
        	String fieldCode = sequenceDto.getFieldCode();
        	
        	if(group!=null){
	        	boolean judge = false;
	        	for(int i = 0;i<group.length;i++){
		        if(fieldCode.equals(group[i])){
		        		judge = true;
		        		break;
		        	};
	        	}
	        	if(!judge){
	        		continue;
	        	}
        	}
        	//根据冲账循序进行冲账
        	BigDecimal payMoney = BigDecimal.ZERO.setScale(2);//未还金额
        	BigDecimal trueMoney = BigDecimal.ZERO.setScale(2);//实还金额
        	McfeReversalDetailDTO reversalDto = new McfeReversalDetailDTO();
        	if("principal".equals(fieldCode)){
        		reversalDto.setTransactionName("本金");
        		reversalDto.setTransactionCode("principal");
        		
        		// 依据配置决定冲本金金额
        		// 当配置为Y时，放款T+1日开始扣款，在无展期情况下每日扣款金额为150元，扣7天。任意一日未扣取到则将其金额进行累加到下一扣款日中
        		//           如果做了展期则扣款日减一天
        		if(StringUtils.equalsIgnoreCase("Y", "N")) {
        			payMoney = plan.getPrincipal().subtract(plan.getPrincipalAct()).subtract(plan.getPrincipalWaive());
        			//如果还款金额大于当期应还本金则冲销对应当期应还本金,否则还款金额有多少则冲销多少本金
        			if(custRepaymentAmount.compareTo(allNeedRepaymentAmount) >= 0){
        				amount = amount.subtract(payMoney);
            			plan.setPrincipalAct(plan.getPrincipalAct().add(payMoney));
            			moneyMap.put("principal", payMoney);
            			trueMoney = payMoney;
        			}else if(amount.compareTo(currentPaymenPrincipal)>=0 && !StringUtils.equals("2", mcfeRepaymentFlowDTO.getPayType())) {
        				plan.setPrincipalAct(plan.getPrincipalAct().add(currentPaymenPrincipal));
        				moneyMap.put("principal", currentPaymenPrincipal);
        				amount = amount.subtract(currentPaymenPrincipal);
        				trueMoney = currentPaymenPrincipal;
        			}else {
        				plan.setPrincipalAct(plan.getPrincipalAct().add(amount));
            			moneyMap.put("principal", amount);
            			trueMoney = amount;
            			amount = BigDecimal.ZERO; 
        			}
        		}else {
        			payMoney = plan.getPrincipal().subtract(plan.getPrincipalAct()).subtract(plan.getPrincipalWaive());
            		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
            			amount = amount.subtract(payMoney);
            			plan.setPrincipalAct(plan.getPrincipalAct().add(payMoney));
            			moneyMap.put("principal", payMoney);
            			trueMoney = payMoney;
            		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
            			plan.setPrincipalAct(plan.getPrincipalAct().add(amount));
            			moneyMap.put("principal", amount);
            			trueMoney = amount;
            			amount = BigDecimal.ZERO;  			
            		}        			
        		}
        	}else if("interest".equals(fieldCode)){
        		reversalDto.setTransactionName("利息");
        		reversalDto.setTransactionCode("interest");
        		payMoney = plan.getInterest().subtract(plan.getInterestAct()).subtract(plan.getInterestWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setInterestAct(plan.getInterestAct().add(payMoney));
        			moneyMap.put("interest", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setInterestAct(plan.getInterestAct().add(amount));
        			moneyMap.put("interest", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("consultingFee".equals(fieldCode)){
        		reversalDto.setTransactionName("咨询费");
        		reversalDto.setTransactionCode("consultingFee");
        		payMoney = plan.getConsultingFee().subtract(plan.getConsultingFeeAct()).subtract(plan.getConsultingFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setConsultingFeeAct(plan.getConsultingFeeAct().add(payMoney));
        			moneyMap.put("consultingFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setConsultingFeeAct(plan.getConsultingFeeAct().add(amount));
        			moneyMap.put("consultingFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        		
        	}else if("managementFee".equals(fieldCode)){
        		reversalDto.setTransactionName("管理费");
        		reversalDto.setTransactionCode("managementFee");
        		
        		// 依据配置决定冲本金金额
        		// 当配置为Y时，放款T+1日开始扣款，在无展期情况下每日扣款金额为150元，扣7天。任意一日未扣取到则将其金额进行累加到下一扣款日中
        		//           如果做了展期则扣款日减一天
        		if(StringUtils.equalsIgnoreCase("Y", "N")) {
        			payMoney = plan.getManagementFee().subtract(plan.getManagementFeeAct()).subtract(plan.getManagementFeeWaive());
        			//如果还款金额大于当前应还管理费则冲销对应前应还管理费,否则还款金额有多少则冲销多少管理费
        			if(custRepaymentAmount.compareTo(allNeedRepaymentAmount) >= 0){
        				amount = amount.subtract(payMoney);
            			plan.setManagementFeeAct(plan.getManagementFeeAct().add(payMoney));
            			moneyMap.put("managementFee", payMoney);
            			trueMoney = payMoney;
        			}else if(amount.compareTo(currentPaymentManagement)>=0  && !StringUtils.equals("2", mcfeRepaymentFlowDTO.getPayType())) {
        				plan.setManagementFeeAct(plan.getManagementFeeAct().add(currentPaymentManagement));
        				moneyMap.put("managementFee", currentPaymentManagement);
        				amount = amount.subtract(currentPaymentManagement);
        				trueMoney = currentPaymentManagement;
        			}else {
        				plan.setManagementFeeAct(plan.getManagementFeeAct().add(amount));
            			moneyMap.put("managementFee", amount);
            			trueMoney = amount;
            			amount = BigDecimal.ZERO; 
        			}
        		}else {
        			payMoney = plan.getManagementFee().subtract(plan.getManagementFeeAct()).subtract(plan.getManagementFeeWaive());
            		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
            			amount = amount.subtract(payMoney);
            			plan.setManagementFeeAct(plan.getManagementFeeAct().add(payMoney));
            			moneyMap.put("managementFee", payMoney);
            			trueMoney = payMoney;
            		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
            			plan.setManagementFeeAct(plan.getManagementFeeAct().add(amount));
            			moneyMap.put("managementFee", amount);
            			trueMoney = amount;
            			amount = BigDecimal.ZERO;
            		}        			
        		}
        	}else if("penaltyFee".equals(fieldCode)){
        		reversalDto.setTransactionName("违约金");
        		reversalDto.setTransactionCode("penaltyFee");
        		payMoney = plan.getPenaltyFee().subtract(plan.getPenaltyFeeAct()).subtract(plan.getPenaltyFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setPenaltyFeeAct(plan.getPenaltyFeeAct().add(payMoney));
        			moneyMap.put("penaltyFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setPenaltyFeeAct(plan.getPenaltyFeeAct().add(amount));
        			moneyMap.put("penaltyFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("lateFee".equals(fieldCode)){
        		reversalDto.setTransactionName("滞纳金");
        		reversalDto.setTransactionCode("lateFee");
        		payMoney = plan.getLateFee().subtract(plan.getLateFeeAct()).subtract(plan.getLateFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setLateFeeAct(plan.getLateFeeAct().add(payMoney));
        			moneyMap.put("lateFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setLateFeeAct(plan.getLateFeeAct().add(amount));
        			moneyMap.put("lateFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("preTerminateFee".equals(fieldCode)){
        		reversalDto.setTransactionName("提前结清费");
        		reversalDto.setTransactionCode("preTerminateFee");
        		payMoney = plan.getPreTerminateFee().subtract(plan.getPreTerminateFeeAct()).subtract(plan.getPreTerminateFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setPreTerminateFeeAct(plan.getPreTerminateFeeAct().add(payMoney));
        			moneyMap.put("preTerminateFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setPreTerminateFeeAct(plan.getPreTerminateFeeAct().add(amount));
        			moneyMap.put("preTerminateFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("miscFee".equals(fieldCode)){
        		reversalDto.setTransactionName("杂费");
        		reversalDto.setTransactionCode("miscFee");
        		payMoney = plan.getMiscFee().subtract(plan.getMiscFeeAct()).subtract(plan.getMiscFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setMiscFeeAct(plan.getMiscFeeAct().add(payMoney));
        			moneyMap.put("miscFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setMiscFeeAct(plan.getMiscFeeAct().add(amount));
        			moneyMap.put("miscFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}else if("platformFee".equals(fieldCode)){
        		reversalDto.setTransactionName("平台费");
        		reversalDto.setTransactionCode("platformFee");
        		payMoney = plan.getPlatformFee().subtract(plan.getPlatformFeeAct()).subtract(plan.getPlatformFeeWaive());
        		if(amount.compareTo(payMoney)==1&&payMoney.compareTo(BigDecimal.ZERO) > 0){
        			amount = amount.subtract(payMoney);
        			plan.setPlatformFeeAct(plan.getPlatformFeeAct().add(payMoney));
        			moneyMap.put("platformFee", payMoney);
        			trueMoney = payMoney;
        		}else if(payMoney.compareTo(BigDecimal.ZERO) > 0){
        			plan.setPlatformFeeAct(plan.getPlatformFeeAct().add(amount));
        			moneyMap.put("platformFee", amount);
        			trueMoney = amount;
        			amount = BigDecimal.ZERO;
        		}
        	}
        	
        	if(trueMoney.compareTo(BigDecimal.ZERO) > 0){
        		reversalDto.setCustCardNo(mcfeRepaymentFlowDTO.getCustCardNo());
        		reversalDto.setCustName(mcfeRepaymentFlowDTO.getCustName());
        		reversalDto.setMobile(mcfeRepaymentFlowDTO.getMobile());
        		reversalDto.setLoanId(mcfeRepaymentFlowDTO.getLoanId());
        		reversalDto.setCreatedBy(createBy);
        		reversalDto.setUpdatedBy(updateBy);
        		reversalDto.setTransctionSeq(mcfeRepaymentFlowDTO.getTransctionSeq());
        		reversalDto.setAmount(trueMoney);
        		reversalDto.setReversalAmount(trueMoney);
        		reversalDto.setRemark("");
        		reversalDto.setTransationDate(date);
        		reversalDto.setReversalDate(date);
        		reversalDto.setPlanCode(plan.getPlanCode());
        		reversalList.add(reversalDto);
        	}
    		
        	if(amount.compareTo(BigDecimal.ZERO) < 1){
        		break;
        	}
        }
         
        BigDecimal needAmount = plan.getPrincipal().subtract(plan.getPrincipalAct()).add(plan.getInterest()).subtract(plan.getInterestAct())
        		.add(plan.getManagementFee()).subtract(plan.getManagementFeeAct()).add(plan.getPenaltyFee()).subtract(plan.getPenaltyFeeAct())
        		.add(plan.getLateFee()).subtract(plan.getLateFeeAct()).add(plan.getPlatformFee()).subtract(plan.getPlatformFeeAct())
        		.add(plan.getMiscFee()).subtract(plan.getMiscFeeAct()).subtract(plan.getPrincipalWaive()).subtract(plan.getInterestWaive())
        		.subtract(plan.getConsultingFeeWaive()).subtract(plan.getManagementFeeWaive()).subtract(plan.getPenaltyFeeWaive()).subtract(plan.getLateFeeWaive())
        		.subtract(plan.getPreTerminateFeeWaive());
        
        //定义当前应还款金额
        BigDecimal currentPaymentAmount = BigDecimal.ZERO;
        if(StringUtils.equalsIgnoreCase("Y", "N")) {
        	currentPaymentAmount = currentPaymenPrincipal.add(currentPaymentManagement).add(plan.getInterest()).subtract(plan.getInterestAct())
        			.add(plan.getPenaltyFee()).subtract(plan.getPenaltyFeeAct()).add(plan.getLateFee()).subtract(plan.getLateFeeAct()).add(plan.getPlatformFee())
        			.subtract(plan.getPlatformFeeAct()).add(plan.getMiscFee()).subtract(plan.getMiscFeeAct()).subtract(plan.getInterestWaive())
        			.subtract(plan.getPenaltyFeeWaive()).subtract(plan.getLateFeeWaive()).subtract(plan.getPreTerminateFeeWaive());
        }
        if(needAmount.compareTo(BigDecimal.ZERO) < 1){
        	plan.setStatus(MarvelsConstant.PAYMENT_PLAN_STATUS_COMPLETE);//如果该笔还款计划金额应还与实还金额差值为零则修改状态为完成
        	plan.setPaymentDateAct(date);
        }else if(plan.getStatus() == MarvelsConstant.CONTRACT_ACCOUNT_STATUS_DELQ && custRepaymentAmount.compareTo(currentPaymentAmount)>=0) {
        	plan.setStatus(MarvelsConstant.PAYMENT_PLAN_STATUS_NORMAL);
        	plan.setDelqDays(0);
        }
        plan.setUpdatedBy(MarvelsConstant.SYSTEM_USER);
        plan.setUpdatedDate(date);
        moneyMap.put("amount", amount);
        System.out.println("冲账结果：" + com.alibaba.fastjson.JSONObject.toJSONString(moneyMap) + "，当前剩余应还：" + needAmount);
	}
}
